1,ToArray 方法
从 IEnumerable<T> 创建一个数组。
string[] names = { "郭靖", "李莫愁", "黄蓉", "黄药师" }; var query = from n in names where n.IndexOf("黄") > -1 select n; //转换成一个数组,这句会导致查询立即执行 string[] newName = query.ToArray(); foreach (var s in newName) { Console.Write(s + " "); } //输出:黄蓉 黄药师
2,ToList 方法
从 IEnumerable<T> 创建一个 List<T>。
string[] names = { "郭靖", "李莫愁", "黄蓉", "黄药师" }; var query = from n in names where n.IndexOf("黄") > -1 select n; //转换成一个List<string>,这句会导致查询立即执行 List<string> lstName = query.ToList(); foreach (var s in lstName) { Console.Write(s + " "); } //输出:黄蓉 黄药师
3,ToDictionary 方法
根据指定的键选择器函数,从 IEnumerable<T> 创建一个 Dictionary<TKey, TValue>。这个方法有多个重载版本。
注意:如果选择的Key在转换中出现重复,将会引发异常。
private class GuestInfo { public int ID { get; set; } public string Name { get; set; } } private void TestLinq() { List<GuestInfo> guests = new List<GuestInfo>{ new GuestInfo{ID =100,Name="Bill"}, new GuestInfo{ID =101,Name="Jeffrey"}, new GuestInfo{ID =102,Name="Killy"}, new GuestInfo{ID =103,Name="Lucy"} }; //以ID为键,创建一个Dictionary<int,GuestInfo>类型的字典 //注意了:如果key重复,这里要抛出异常 var dicName = guests.Select(g => g).ToDictionary(g => g.ID); foreach (var s in dicName) { Console.WriteLine("key={0},value={1}", s.Key, s.Value.Name); } //输出: //key=100,value=Bill //key=101,value=Jeffrey //key=102,value=Killy //key=103,value=Lucy }
4,ToLookup 方法
从 IEnumerable<T> 生成一个泛型 Lookup<TKey, TElement>。这个方法和ToDictionary很相似,只不过Dictionary的key和value是一对一的,而LookUp的key和value是1对多的,类似于分组的概念。
private void ToLookupDemo() { //将序列转化成LookUp<Tkey,Telement>的序列 List<GuestInfo> guests = new List<GuestInfo>{ new GuestInfo{ID =100,Name="Bill"}, new GuestInfo{ID =101,Name="Beffrey"}, new GuestInfo{ID =102,Name="Killy"}, new GuestInfo{ID =103,Name="Lucy"} }; //将Name的第一个字母作为键,这样前面的两个Bill和Beffrey就会是同一个键 ILookup<string, GuestInfo> lookup = guests.ToLookup(g => g.Name.Substring(0, 1)); foreach (var k in lookup) { Console.WriteLine("Key:" + k.Key); foreach (var v in k) { Console.WriteLine("Name={0}", v.Name); } Console.WriteLine("----------------------------------"); } //输出: //Key:B //Name=Bill //Name=Beffrey //---------------------------------- //Key:K //Name=Killy //---------------------------------- //Key:L //Name=Lucy //---------------------------------- }
5,SequenceEqual 方法
比较两个序列是否相等。可以指定比较器,如果不指定,就使用默认的比较器。
private class GuestInfo { public int ID { get; set; } public string Name { get; set; } } //自定义比较器 private class GuestInfoComparer : IEqualityComparer<GuestInfo> { #region IEqualityComparer<GuestInfo> public bool Equals(GuestInfo x, GuestInfo y) { if (object.ReferenceEquals(x, y)) return true; if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null)) return false; return x.ID == y.ID && x.Name == y.Name; } public int GetHashCode(GuestInfo obj) { if (obj == null) return 0; int hashName = obj.Name == null ? 0 : obj.Name.GetHashCode(); int hashId = obj.ID.GetHashCode(); return hashName ^ hashId; } #endregion } private void TestLinq() { GuestInfo g1 = new GuestInfo { ID = 100, Name = "Bill" }; GuestInfo g2 = new GuestInfo { ID = 101, Name = "Jeffrey" }; List<GuestInfo> lst1 = new List<GuestInfo> { g1, g2 }; List<GuestInfo> lst2 = new List<GuestInfo> { g1, g2 }; bool result = lst1.SequenceEqual(lst2);//由于lst1,lst2引用了相同的对象 Console.WriteLine("result #1 ={0}", result);//所以结果是:true //改变lst2,但里面的值的内容和lst1完全相同 lst2 = new List<GuestInfo>{ new GuestInfo { ID = 100, Name = "Bill" }, new GuestInfo { ID = 101, Name = "Jeffrey" } }; result = lst1.SequenceEqual(lst2);//由于lst1,lst2引用了不同的对象 Console.WriteLine("result #2 ={0}", result);//所以结果是:false //用自定义比较器,比较两个序列 //lst1,lst2虽然引用了不同的对象,但比较器会比较他们的值,值相等就认为是相同 result = lst1.SequenceEqual(lst2, new GuestInfoComparer()); Console.WriteLine("result #3 ={0}", result);//所以结果是:true //运行结果: //result #1 =True //result #2 =False //result #3 =True }
6,First 方法
返回序列中的第一个元素。
注意:如果序列中不包含元素,会引发异常。
string[] names = { "郭靖", "李莫愁", "黄蓉", "黄药师" }; var query = from n in names select n; var first = query.First(); Console.WriteLine(first); //输出:郭靖
7,FirstOrDefault方法
返回序列中的第一个元素。如果序列为空,返回默认值。
string[] names = { "郭靖", "李莫愁", "黄蓉", "黄药师" }; var query = from n in names where n.Length == 5 select n; //返回第一个元素或默认值 var first = query.FirstOrDefault(); Console.WriteLine(first); //输出:null
8,Last 方法
返回序列的最后一个元素。
注意:和First一样,没有元素时会抛出异常。
string[] names = { "郭靖", "李莫愁", "黄蓉", "黄药师" }; var query = from n in names select n; //返回最后一个元素 var last = query.Last(); Console.WriteLine(last); //输出:黄药师
9,LastOrDefault 方法
返回序列的最后一个元素。如果序列为空,返回默认值。
string[] names = { "郭靖", "李莫愁", "黄蓉", "黄药师" }; var query = from n in names where n.Length == 5 select n; //返回最后一个元素或默认值 var last = query.LastOrDefault(); Console.WriteLine(last); //输出:null
10,Single 方法
返回序列中的单个元素。
注意:如果序列包含多个元素,则会引发异常。
string[] names = { "郭靖", "李莫愁", "黄蓉", "黄药师" }; var query = from n in names where n.IndexOf("郭") > -1 //数组里只有一个姓郭的。 select n; //返回单一元素 var single = query.Single(); Console.WriteLine(single); //输出:郭靖
11,SingleOrDefault 方法
返回序列中的单个元素。如果序列为空,则返回默认值。
注意:如果序列有多个(>1)元素,同样会引发异常。
string[] names = { "郭靖", "李莫愁", "黄蓉", "黄药师" }; var query = from n in names where n.IndexOf("郭襄") > -1 //数组里没有郭襄。 select n; //返回单一元素或默认元素 var single = query.SingleOrDefault(); Console.WriteLine(single); //输出:null