在上根据作者的步骤学习后一些入门,整理一下.(感觉Linq就是一些C#语言的新特性集合的产物).
首先提供一个功能用于把一个类的属性的值全部输出.因为通用性.用上反射取值.
Code
1 public static class Reflector
2 {
3 public static void write<T>(T s)
4 {
5 Type type = typeof(T);
6 System.Reflection.PropertyInfo[] ms = type.GetProperties();
7 foreach (System.Reflection.PropertyInfo minfo in ms)
8 {
9 if (minfo.GetValue(s, null) != null)
10 {
11 string value = minfo.GetValue(s, null).ToString();
12 Console.Write("{0}:{1} ", minfo.Name, value);
13 }
14 }
15 Console.WriteLine();
16 }
17 public static void write<T>(IEnumerable<T> e)
18 {
19 if (e == null)
20 return;
21 foreach (T s in e)
22 {
23 write<T>(s);
24 }
25
26 }
27 }
先定义自然界中的书.如下
Code
1 public class Book
2 {
3
4 public string Title { get; set; }
5
6 public float Price { get; set; }
7
8 public string Author { get; set; }
9
10 public string ISBN { get; set; }
11 }
有下例要求.有很多的书.要求你根据相关条件查找出满足条件的书.
我们分析如下.很多的书---IList<Book>.相关条件---public delegate bool DelegateWhere(Book book);
满足条件的书---IList<Book>.
查找过程如下.
Code
1 //C# 3.0里还为我们提供了扩展方法
2 public static IList<Book> Where(this IList<Book> books, DelegateWhere condition)
3 {
4 IList<Book> results = new List<Book>();
5 foreach (Book book in books)
6 {
7 if (condition(book))
8 {
9 results.Add(book);
10 }
11 }
12 return results;
13 }
以上只是实现.那么人要查找.那么如何来做这一动作了.
首先是上面查找的相关条件的确定.那么有人问.那么还不是要定义一个条件(就是委托).然后人查找是加上条件.能不能直接一
步到位(比喻人可以先知道条件然后查找,也可以查找时才知道条件吗,是不是).C# 2.0为我们提供了匿名方法,能让我们查找时
输入条件.如下var filter = books.Where(delegate(Book book) { return book.Title == "Linq"; });
大家可能有点不清楚.这个books就是IList<Book>,而Where就是他的扩展方法.大家可以看到这个查找方式不是很漂亮,因此
C# 3.0给我们提供了Lambda表达式,请看如下简化如下var filter1 = books.Where(book => book.Title == "Linq");
可以看到漂亮很多.简要说明一下
//也可以多个输入参数,逗号分隔,别忘记小括号
//(x,y) => x+y等价与
//delegate(int x,int y){return x+y;}
而select,等都可以通过如上方式实现.大家可能注意到.以上方法没有通过性.而Linq是对实现IEnumerable接口的可能通用的.
如下按上面的前二步我们重复一下.就可以实现对IEnumerable接口通用.
Code
1 public delegate TOutput MyDelegate<TInput,TOutput>(TInput input);
2 public static class Extension
3 {
4 public static IEnumerable<TInput> where<TInput>(this IEnumerable<TInput> self,MyDelegate<TInput,bool> filter)
5 {
6 foreach (TInput each in self)
7 {
8 if (filter(each))
9 //C# 2.0里出现的一个关键字,返回一个迭代器
10 yield return each;
11 }
12 }
13 public static IEnumerable<TOutput> select<TInput,TOutput>(this IEnumerable<TInput> self, MyDelegate<TInput, TOutput> selector)
14 {
15 foreach (TInput each in self)
16 {
17 yield return selector(each);
18 }
19 }
20 }
上面的委托其实MS已经给我们实现,
Code
1//在System.Core.dll下的System命名空间下你会发现有这么几个泛型的委托:
2
3//无参,有一个返回值
4public delegate TResult Func<TResult>();
5//一个参数一个返回值
6public delegate TResult Func<T, TResult>(T arg);
7//两个参数一个返回值
8public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
9//三个参数一个返回值
10public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
11//四个参数一个返回值
12public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
还有大家在上面可能看到yield return关键字.这是C# 2.0里出现的一个关键字,返回一个迭代器.
通过如上.我们可以写如下语句.
Code
1IList<Book> books = new List<Book> {
2 // C# 3.0为你提供了对象集合初始化器
3 new Book { Title = "Inside COM", ISBN = "123-456-789",Price=20 },
4 new Book { Title = "Inside C#", ISBN = "123-356-d89",Price=100 },
5 new Book { Title = "Linq", ISBN = "123-d56-d89", Price = 120 }
6 };
7var filter2 = books.where(book => book.Title.StartsWith("I")).select(book => new { Key = book.Title, Value = book.Price });
8Reflector.write(filter2);
在我机器上测试如果如下.(Reflector.write请看最上面的那个类).
实践和理论完全相符.大家看下面的是不是有点Linq的影子了.
最后我们把如下Linq语句解析如下.
Code
1 //from关键字后面跟着的是Func委托的输入参数
2 //in关键字后面跟着一个IEnumerable类型
3 //where,orderby,select对应着那些扩展方法
4 //那些扩展方法接受的委托的输入参数就是from后面的book。C# 3.0的var关建字
5 var result = from book in books
6 where book.Title.StartsWith("I")
7 orderby book.Price
8 //隐式类型局部变量
9 select new { Key=book.Title,Value = book.Price};
10
11 //实际转换成如下
12 books.Where<Book>(delegate(Book book)
13 {
14 return book.Title.StartsWith("I");
15 }).OrderBy<Book, float>(delegate(Book book)
16 {
17 return book.Price;
18 }).Select(delegate(Book book)
19 {
20 return new { Key = book.Title, Value = book.Price };
21 });
22 Reflector.write(result);
在Linq里的关键字如in,from,where大家可以想象成C++里的define,实际是一些函数和变量定义.(不知理解是否有误.有的请指出.在此谢谢)
写在最后.大家可以看到如上有许多的大家不平常用的C#语言新性质.组合在一起的功能如此强大.呵呵.
本人水平有限.有什么错误谢谢大家的指出.