关于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推出的新的东西是不会让我们失望的