就要开始看MVC的实际代码了,现在先复习一个Linq的语法。
看的是《C#4.0 IN A NUTSHELL》(《C#核心技术》)的英文版,适应了扩展方法和查询表达式等一些特性,记录如下:
第8章 Linq Queries
如
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>>
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等也是扩展方法,也有相应的定义形式。
如下代码:
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 + "|");