读书人

关于LINQ的匿名类型的使用讨论(欢迎大

发布时间: 2012-02-02 23:57:14 作者: rapoo

关于LINQ的匿名类型的使用讨论(欢迎大家进来拍砖)
今天早上看了论坛一位朋友的帖子,是关于C#的匿名类型的,详细请看http://topic.csdn.net/u/20071213/19/45ee97a5-94c1-4895-9849-d6ce6ae21e2a.html
为什么要使用匿名类型?除了方便,我想不出其他的好处。但这种方便是建立在合适的场景下的,当匿名类型不再方便的时候,我们还要执着地使用匿名类型吗?不废话,
我构造一个类似的场景,请看下图:(看不到图片下载附件)

这是大家都熟悉的Northwind数据库里面的2个表。这里,我说明的是匿名类型的重用问题。个人觉得,匿名类型只适合在方法内部“短暂"地使用,如果你
一定要在方法间去重用的话不是不可以,但是那会很麻烦,得不偿失,因为这样匿名类型的方便性被抹杀了。请看下面的代码:

C# code
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Collections;using System.Reflection;namespace AnonymouseType{    class AnonymouseSolve    {        //取得ProductID,ProductName,CategoryName        public IEnumerable GetAnonymousResult()        {            NorthwindDataContext db = new NorthwindDataContext();            var result = db.Products.Select(p => new            {                产品ID = p.ProductID,                产品名称 = p.ProductName,                类别名称 = p.Category.CategoryName            });            return result;        }        //取得ProductID,ProductName,CategoryName的前10条记录        public IEnumerable GetTop10Result(IEnumerable _result)        {            var result = _result.Cast<object>();            var set = result.Select(p => new            {   //利用反射取得传入的匿名类型的信息                产品ID = p.GetType().GetProperty("产品ID").GetValue(p, null).ToString(),                产品名称 = p.GetType().GetProperty("产品名称").GetValue(p, null).ToString(),                类别名称 = p.GetType().GetProperty("类别名称").GetValue(p, null).ToString()            }).Take(10);            return set;        }        public IEnumerable GetTop10Result(object IEnumerableOject)        {            var result = (IEnumerable)IEnumerableOject;            return this.GetTop10Result(result);        }    }}

通过上面的代码,可以实现匿名类型在不同的方法间传递,但是,那是我们不得不采取反射为代价的
事实上,新的C#语言构造一个只包含属性的类型如此简单,在这种情况下我们为什么一定要使用匿名类型呢?
C# code
namespace AnonymouseType{    class Linker    {        public int ProductID        {            get;            set;        }        public string ProductName        {            set;            get;        }        public string CategoryName        {            get;            set;        }    }}

上面的几句代码就定义了一个程序员可"触摸"的类型,那么查询改成这样岂不更好?
C# code
        public IEnumerable<Linker> GetAnonymousResult()        {            NorthwindDataContext db = new NorthwindDataContext();            var result = db.Products.Select(p => new Linker            {               ProductID=p.ProductID,               ProductName=p.ProductName,               CategoryName=p.CategoryName            })            return result;        }      //这里的var实际上是IEnumerable<Linker>      //该方法的返回值完全适用于任何需要使用linq的场合


所以说,真的需要在取得的数据集中再使用linq,那么,就别用匿名类型了,因为提取匿名类型很麻烦
最后给出测试结果:
代码:
C# code
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Collections;using System.Reflection;namespace AnonymouseType{    class Program    {        static void Main(string[] args)        {            AnonymouseSolve solve = new AnonymouseSolve();            foreach (var item in solve.GetTop10Result(solve.GetAnonymousResult()))            {                Console.WriteLine("-----------------------------------------");                Type itemType = item.GetType();                Console.WriteLine("产品ID:" + itemType.GetProperty("产品ID").GetValue(item, null));                Console.WriteLine("产品名称:" + itemType.GetProperty("产品名称").GetValue(item, null));                Console.WriteLine("类别名称:" + itemType.GetProperty("类别名称").GetValue(item, null));                Console.WriteLine("-----------------------------------------");                Console.WriteLine();            }            var obj = (object)solve.GetAnonymousResult();            foreach (var item in solve.GetTop10Result(obj))            {                Console.WriteLine("-----------------------------------------");                Type itemType = item.GetType();                Console.WriteLine("产品ID:" + itemType.GetProperty("产品ID").GetValue(item, null));                Console.WriteLine("产品名称:" + itemType.GetProperty("产品名称").GetValue(item, null));                Console.WriteLine("类别名称:" + itemType.GetProperty("类别名称").GetValue(item, null));                Console.WriteLine("-----------------------------------------");                Console.WriteLine();            }        }    }} 



结果如图:



[解决办法]
向自已提问?嘿嘿。爱学习。

以我的观点来看,作为一种语言特性,它的用处可能不一定非常大。比如:Office可能你就没有乃至它多少功能,但其它的功能它都具备了。
我想,它之所以引入这个,仅仅是为了方便而已。既然是为了方便,那么做到只在方便的时候使用到它就OK了。在构造的方法之外使用它,我觉得意义不大。
[解决办法]
小弟也在考虑linq重用的问题,不过小弟始终觉得ms推出的新的东西是不会让我们失望的

读书人网 >.NET

热点推荐