乘势社会之进步,游戏产业逐步升温,各大耍企业盈利得盆满钵盈,例如国内娱乐产业龙头老大腾讯,在揭示了2017年第一季度财报中,Q1总收入495.52亿,同比提高55%,其中网络娱乐收入及228.11亿,同比提高34%。游戏收入占总收入的46%。

  .NET中之LINQ对于操作集合对象提供了广大底利,使得我们得于C#屡遭运用类似于SQL语句的措施对聚集中的靶子开展检索、分组、统计等。使用LINQ写出来的代码简单明了,省去了咱本来欲采用大量for循环或者foreach循环才会促成的法力。众所周知,通过LINQ查询所返的结果一般的话是一个为var所标识的匿名类型,该种继承自IEnumerable接口,我们得以一直用她绑定到外一个数绑定控件,如DropDownList,ListBox,DataGridView等。但这边有一个题目,对于DataGridView(WinForm版)来说,如果下LINQ返回的匿名对象开展数量绑定的话,会失掉DataGridView中单击列标题进行数量排序的职能,这是以DataGridView不可知打一个匿名对象吃取得到开展多少排序的切实可行规则。要解决这个题材,你得于这匿名对象编排具体的排序算法,不过最好简易的做法还是用以此匿名对象转换成为我们所熟识的聚众对象,如DataTable,然后再度绑定到DataGridView中。

此外,据腾讯发布之篇章《2017华夏互联网趋势报告:游戏单位时长变现效率高》中,中国当2016年超越美国,成为全世界率先好游戏市场,全国游戏市场收入近250亿美元。数据而图一律所显示。

  查找msdn,你可找到以LINQ to
DataSet的结果转换成DataTable的主意。下面的代码有来源于msdn上的介绍,http://msdn.microsoft.com/zh-cn/library/bb396189(v=vs.90).aspx

另外根据CNNIC发布的第39次《中国互联网络发展统计报告》中展示,截止2016年12月,我国网络游戏用户规模高达4.17亿,占整体网民的57.0%,较去年增强2556万丁。手机网络娱乐用户规模比去年底明显提升,达到3.52亿,较去年底增强7239万人,占手机网民的50.6%。数据如果图二所著。

// Bind the System.Windows.Forms.DataGridView object
// to the System.Windows.Forms.BindingSource object.
dataGridView.DataSource = bindingSource;

由此可以见到,游戏产业是这么地可以,游戏是这般地为人口“沉迷”。

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

这就是说也什么游戏会这样给玩家群体的欢迎?我道好从动机理论与反映机制进行探索。

DataTable orders = ds.Tables[“SalesOrderHeader”];

每当同样统成熟之角色扮演游戏中,有着“完整的晋级机制”、“明确知晓的成就目标”、“充分的自由度”、“完全量化、精确化的报告机制”,
其中“完全量化、精确化的上报机制”尤为重要。
要么说一样统成功之一日游到体现了J·理查德·哈尔曼的五独核心工作维度:技能的多样性、任务的完整性、任务之要害、工作的自主性、反馈。

// Query the SalesOrderHeader table for orders placed 
// after August 8, 2001.
IEnumerable<DataRow> query =
    from order in orders.AsEnumerable()
    where order.Field<DateTime>(“OrderDate”) > new DateTime(2001, 8, 1)
    select order;

1、完整的晋升机制——清晰的“目标”、可行的“道路”,“人生”不再盲目。“升迁机制”则靠的凡耍中角色的各指标,例如角色扮演类游戏的枪杆子值、战斗力、装备属性、角色等级和棋牌类游戏中之胜场、胜率、财产等,它们的加强都随一定的业内,一定之计算公式,有序的增进。从某种程度上说,这满足了玩家心理上的“公平”述求。

// Create a table from the query.
DataTable boundTable = query.CopyToDataTable<DataRow>();

           清晰的玩“人生”目标                                        
   

// Bind the table to a System.Windows.Forms.BindingSource object, 
// which acts as a proxy for a System.Windows.Forms.DataGridView object.
bindingSource.DataSource = boundTable;

2、数据化的人物属性,助玩家充分认识“自己”。按部就班统计,有39.2%底玩家表示偏好“练级”,27.1%的玩家偏好“收集装备”,13.9%底玩家表示偏好“打钱”。所以,玩家的对象之一即是提色等级上升一级后,战斗力则成为2000,再配上同码漂亮之配备,战斗力变为3000,然后花钱买进了同一宗再好的配备,战斗力变为了4000。相对而言数据前后,可以充分了解的比有战斗力“数据”的歧异。而且,在PK
之前,玩家还好比敌方与我方的“数据”差异,大概而快地比较起差异大小,从而规范判断发生胜算程度,然后又做出极端合情合理之“PK”决定。对此玩家来说,这些数量是显而易见的、及时的、可以掌控的,从而为玩家“完美掌控”其打角色的,做到“知己知彼”,与队友“有效沟通”,及时作出合理“决策”,更便于沾满足感、成就感。

  不过这办法无是我们所期待的!原因是其中的泛型类型必须是DataRow而不能够是由定义类型。怎么处置吧?我们而免可以拿这个方法修改一下叫它们能够支持任意档次?

         数据化的人物属性,助玩家充分认识“自己                          
                 

  还记得从.NET
3.0开便提供的一个功力为?C#扩张方法。它同意我们为现有项目受到“添加”方法,而不论需创建新的派生类型、重新编译或因其他方法修改原始类型。看看msdn上之牵线,先来熟悉一下呀是C#推而广之方法吧!http://msdn.microsoft.com/zh-cn/library/bb383977.aspx

据此,在“中国网络游戏用户青睐之打内外活动”问题之调研中,才见面分别产生60.1%及51.5底玩家表示欣赏好“双倍经验”和“增加掉宝和收益”。统计结果要图五所出示。

  C#壮大方法是为现有项目“添加”一个艺术,现有项目可以是着力数据类(如int,string等),也得以是从定义类型。定义规则是扩张方法要定义在一个肆意命名的静态类吃,该办法必须是静态方法,可以随便命名,方法的参数列表必须以this关键字开头,第二独就是为使推而广之的数据类型,第三单凡是一个变量名为,同时参数列表中允许定义多独其他参数为促成方式的重载。来拘禁一个例。

3、“丰富多彩的目标,量化进程,成就感爆棚”。通过打本身的设定,不同游戏所有不同的“明确了解的就目标”,例如通关,PK战斗胜利等,这些目标的得吗,距离成功产生多格外差距都好肯定的坐多少的样式反映。例如,关卡一共发生5关,玩家就经过了4牵连,还残留一拖累没过;玩家当PK
中战败给了其余玩家,其角色叫另外玩家“打败”,游戏角色死亡,电脑屏幕“黑屏”。再者,游戏制造商往往不会见将嬉戏难度设定得极其要命,否则即是自杀他们后路。

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ‘ ‘, ‘.’, ‘?’ }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}

而且,游戏被尚会见发出各个种排行榜,各种名,例如排行榜在红游戏《守望先锋》中有“战力排行榜”第***名,称号在现最为暖、最赚钱游戏《英雄联盟》有青铜、白银、黄金、铂金、钻石、大师、最强上相当于。这些招数确实会大地激励大部分玩家的好胜心等“自我实现需求”,再长戏制造商有意以玩乐被突出“战力”、“称号”的别,例如不同“称号”或“战力”的玩家所有不同的边框、图标、奖励等,从而玩家会激发起重新特别之“上进”动力。并且以玩家当排行榜中的行差距,距离获得下一个“称号”的差异还是可以理解地因为数的形式展现出,玩家当这种“完全量化、精确化的上报机制面临”及时、准确把握好的速度,不断赢得“进步”的满足感、成就感。

  静态类MyExtensions被定义在命名空间ExtensionMethods中,静态方法WordCount的参数列表中规定了该方式是本着String类型的计进行了扩大。在事实上应用中,你用在代码中加上对ExtensionMethods命名空间的援,然后经String.WordCount()的方法来调用这个扩展方法。是免是老神奇啊?再拘留一个事例。

                   精确化及时反映,准确定位好,获得不断进步的“成就感”
                                           

namespace MyExtension
{
    public static class Test    {
        public static XElement ToXml(this DirectoryInfo dir)
        {
            // TO Do Something
        }
    } 
}

就此自获得满足、成就的“自我实现”动机来说,在游戏过程被,无论是从“进度”还是“结果”,成功再次爱把,因而玩家还便于得充分的满足感、成就感

  上面的代码有对DirectoryInfo类的法进行了扩大,将上述代码补充完整,便得以一直通过下的艺术调用新扩张的不二法门。

4、另外,游戏往往有着“充分的自由度”。一部成功之玩乐拥有多种模式,例如团队竞技,个人竞技或是剧情模式,PK模式,并且相同种模式下又发生两样之玩法。例如团队竞技需要好的协作,配合,这反映了“任务的重中之重”。还有,基于玩法的多样性,游戏中玩家可表达好之想象力,或享受不同的玩法或创着另行多的玩法。这体现了“工作之自主性”和“任务的机要”。

DirectoryInfo dir = new DirectoryInfo(path);
dir.ToXml();

总的说来,人们因某种“自我实现”目标,在戏世界被以合理的“升迁机制”,同时以“完全量化、精确化的举报机制”的援助,动机水平有所更老之“强度”、更鲜明的“方向性”、更强之“坚持性”,从而获取丰富的动力,完美掌控“自己”、完全把“自我实现”目标的经过,因此赢得巨大的满足感、成就感。

  C#扩展方法允许对自定义之路进行扩展,同时同意带参数,支持重载。看下的例子。

可是当我们对比现实情况来拘禁,假如游戏世界是一个忠实是的社会风气,则它好看是“完全数据化”的有血有肉。然而真正的世界并无是这种“完美反馈”的“完全数据化”世界。在具体中,人类没法对好的姣好、身体属性、能力属性等进行宏观合理地量化,因此相对游戏来说,我们无能够博取像娱乐被那样就、准确、量化的反映。所以,人们见面时不知所措,不理解什么样升级自己或者说那个不便理解自己是否出升级,自己的不竭是否管用。没有应声得力的反映,就从未还胜之动力。故现实世界对大多数口的话挺不便“沉迷”。

namespace TestExtendMethod
{
    public class Student
    {
        public string Description()
        {
            return “Student………….”;
        }
        public string Description(string name)
        {
            return “the student’s name is ” + name;
        }
    }

切实毕竟是有血有肉,虚妄毕竟是虚妄。现实的纷繁无法让忽略,人类思想的多样性无法为忽视。人类无比有价之“自我实现”还得是打现实中来。冲前文对游戏之于丁“沉迷”原因的议论和定论,我们可以看出动机理论同申报机制的巨大作用。那么一定,在切切实实中,它的企图也未会见稍微。客观可行地运动机理论及申报机制,无疑可以对人类自己管理推向与团队被员工的军事管制促进来第一的图。

    public static class Extensions
    {
        public static string TestMethod(this Student s)
        {
            return s.Description();
        }

        public static string TestMethod(this Student s, string name)
        {
            return s.Description(name);
        }
    }
}

  于是,自定义的Student类具有了蕴藏一个重载的TestMethod方法,该法允许收取一个string类型的参数或者无参数。

  好了!回到我们的主题上来。既然C#恢宏方法允许我们本着项目丰富方法,那么我们全然好对就有些IEnumerable接口扩展一个CopyToDataTable方法,使其可以以LINQ返回的var匿名类型转换成DataTable。来拘禁下实际的贯彻。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // create sequence 
            Item[] items = new Item[] { new Book{Id = 1, Price = 13.50, Genre = “Comedy”, Author = “Jim Bob”}, 
                                        new Book{Id = 2, Price = 8.50, Genre = “Drama”, Author = “John Fox”},  
                                        new Movie{Id = 1, Price = 22.99, Genre = “Comedy”, Director = “Phil Funk”},
                                        new Movie{Id = 1, Price = 13.40, Genre = “Action”, Director = “Eddie Jones”}};

            var query1 = from i in items
                         where i.Price > 9.99
                         orderby i.Price
                         select i;

            // load into new DataTable
            DataTable table1 = query1.CopyToDataTable();

            this.dataGridView1.DataSource = table1;
        }
    }

    public class Item
    {
        public int Id { get; set; }
        public double Price { get; set; }
        public string Genre { get; set; }
    }

    public class Book : Item
    {
        public string Author { get; set; }
    }

    public class Movie : Item
    {
        public string Director { get; set; }
    }

    public static class DataSetLinqOperators
    {
        public static DataTable CopyToDataTable<T>(this IEnumerable<T> source)
        {
            return new ObjectShredder<T>().Shred(source, null, null);
        }

        public static DataTable CopyToDataTable<T>(this IEnumerable<T> source,
                                                    DataTable table, LoadOption? options)
        {
            return new ObjectShredder<T>().Shred(source, table, options);
        }

    }

    public class ObjectShredder<T>
    {
        private FieldInfo[] _fi;
        private PropertyInfo[] _pi;
        private Dictionary<string, int> _ordinalMap;
        private Type _type;

        public ObjectShredder()
        {
            _type = typeof(T);
            _fi = _type.GetFields();
            _pi = _type.GetProperties();
            _ordinalMap = new Dictionary<string, int>();
        }

        public DataTable Shred(IEnumerable<T> source, DataTable table, LoadOption? options)
        {
            if (typeof(T).IsPrimitive)
            {
                return ShredPrimitive(source, table, options);
            }

            if (table == null)
            {
                table = new DataTable(typeof(T).Name);
            }

            // now see if need to extend datatable base on the type T + build ordinal map
            table = ExtendTable(table, typeof(T));

            table.BeginLoadData();
            using (IEnumerator<T> e = source.GetEnumerator())
            {
                while (e.MoveNext())
                {
                    if (options != null)
                    {
                        table.LoadDataRow(ShredObject(table, e.Current), (LoadOption)options);
                    }
                    else
                    {
                        table.LoadDataRow(ShredObject(table, e.Current), true);
                    }
                }
            }
            table.EndLoadData();
            return table;
        }

        public DataTable ShredPrimitive(IEnumerable<T> source, DataTable table, LoadOption? options)
        {
            if (table == null)
            {
                table = new DataTable(typeof(T).Name);
            }

            if (!table.Columns.Contains(“Value”))
            {
                table.Columns.Add(“Value”, typeof(T));
            }

            table.BeginLoadData();
            using (IEnumerator<T> e = source.GetEnumerator())
            {
                Object[] values = new object[table.Columns.Count];
                while (e.MoveNext())
                {
                    values[table.Columns[“Value”].Ordinal] = e.Current;

                    if (options != null)
                    {
                        table.LoadDataRow(values, (LoadOption)options);
                    }
                    else
                    {
                        table.LoadDataRow(values, true);
                    }
                }
            }
            table.EndLoadData();
            return table;
        }

        public DataTable ExtendTable(DataTable table, Type type)
        {
            // value is type derived from T, may need to extend table.
            foreach (FieldInfo f in type.GetFields())
            {
                if (!_ordinalMap.ContainsKey(f.Name))
                {
                    DataColumn dc = table.Columns.Contains(f.Name) ? table.Columns[f.Name]
                        : table.Columns.Add(f.Name, f.FieldType);
                    _ordinalMap.Add(f.Name, dc.Ordinal);
                }
            }
            foreach (PropertyInfo p in type.GetProperties())
            {
                if (!_ordinalMap.ContainsKey(p.Name))
                {
                    DataColumn dc = table.Columns.Contains(p.Name) ? table.Columns[p.Name]
                        : table.Columns.Add(p.Name, p.PropertyType);
                    _ordinalMap.Add(p.Name, dc.Ordinal);
                }
            }
            return table;
        }

        public object[] ShredObject(DataTable table, T instance)
        {

            FieldInfo[] fi = _fi;
            PropertyInfo[] pi = _pi;

            if (instance.GetType() != typeof(T))
            {
                ExtendTable(table, instance.GetType());
                fi = instance.GetType().GetFields();
                pi = instance.GetType().GetProperties();
            }

            Object[] values = new object[table.Columns.Count];
            foreach (FieldInfo f in fi)
            {
                values[_ordinalMap[f.Name]] = f.GetValue(instance);
            }

            foreach (PropertyInfo p in pi)
            {
                values[_ordinalMap[p.Name]] = p.GetValue(instance, null);
            }
            return values;
        }
    }
}

  
Item,Book,Movie都是起定义类型,扩展方法对IEnumerable泛型接口添加了会支撑任意档次并返DataTable的章程CopyToDataTable,于是,我们得一直对LINQ返回的var匿名类型应用CopyDoDataTable方法并以返回值赋值给DataTable对象。然后以DataTable直接绑定给DataGridView从而获取点击列标题进行数量排序的功能。还有多少复杂一点底利用,给一个代码有的截图。

 

统计 1