学习第四天@Linq查询

就要开始看MVC的实际代码了,现在先复习一个Linq的语法。

看的是《C#4.0 IN A NUTSHELL》(《C#核心技术》)的英文版,适应了扩展方法和查询表达式等一些特性,记录如下:

第8章 Linq Queries

 

  1. 1.       可以使用匿名类型

String[] names = {“Tom”,”Dick”,”Harry”};

正常来写:

IEnumerable<string> filteredNames = names.Where(n => n.Length >= 4);

而偷懒的方法可以这样写:

Var filteredNames = names.Where(n => n.Length >= 4);

系统会自己判断,但其实调试会发现,使用匿名类型并非IEnumerable<string>类型胡,而是

System.Linq.Enumerable.WhereArrayIterator<string>

此外,如果采用表达式方式,则类型又会不一样:

如:

var fileteredNames = from n in name

                                where n.Contains("a")

                                select new { n, name.Length };

 

则类型为

       System.Linq.Enumerable.WhereSelectArrayIterator<string,<>f__AnonymousType0<string,int>>

 

  1. 2.       关于扩展方法

String[] names = {“Tom”,”Dick”,”Harry”,”Mary”,”Jay”};

IEnumerable<string> query = names

 .Where(n => n.Contains(“a”))

 .OrderBy(n => n.Length)

 .Select(n => n.ToUpper());

 它就像一个传送带,先经过Whrere传送带的过滤,把过滤剩下的再送到Sorter传送带排序,最终再将排好序的数据送到Select传送带进行最终的选择。

 

有一个很巧妙的例子可以说明整个过程:

            string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

            IEnumerable<string> filtered = Enumerable.Where(names, n => n.Contains("a"));

            IEnumerable<string> sorted = Enumerable.OrderBy(filtered, n => n.Length);

            IEnumerable<string> finalQuery = Enumerable.Select(sorted, n => n.ToUpper());

 

扩展方法可以使代码看起来更加优雅:

IEnumerable<string> query = names

 .Where(n => n.Contains(“a”))

 .OrderBy(n => n.Length)

 .Select(n => n.ToUpper());

和传统相比:

IEnumerable<string> query =

Enumerable.Select(

 Enumerable.OrderBy(

   Enumerable.Where(

names,n => n.Contains(“a”)

),n => n.Length

),n => n.ToUpper()

     );

 

扩展方法的参数以this开头,如Where的扩展方法定义为:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate>

{

 foreach(TSource element in source)

   if(predicate(element))

     Yield return element;

}

其他的诸如Order,Select等也是扩展方法,也有相应的定义形式。

  1. 3.       Linq的延迟执行

如下代码:

            var numbers = new List<int>() { 1, 2 };

 

            IEnumerable<int> query = numbers.Select(n => n * 10);

            foreach (int n in query) Console.Write(n + "|");

            numbers.Add(2);

            foreach (int n in query) Console.Write(n + "|");

执行的结果将是10|20|

这是因为直到foreach时才计算query的值。

如果要避免这个延迟执行,则可以使用以下操作:

       Toarray,ToList,ToDictionary,ToLookup.

示例如下:

            var numbers = new List<int>() { 1, 2 };

 

            List<int> timesTen = numbers.Select(n => n * 10).ToList();

            foreach (int n in timesTen) Console.Write(n + "|");

            numbers.Clear();

            foreach (int n in timesTen) Console.Write(n + "|");

你可能感兴趣的:(LINQ)