Linq
今天心情非常好,再发一组 Linq、 集合、数组、Lambda、QuerySyntax 的文章
目录
4.3 System.Linq.Lookup <TKey,TElement> 10
4.4 System.Linq.Expressions.Expression 10
5.1 IEnumerable 、IEnumerator 10
5.11 IDictionary <TKey,TValue> 13
5.13.1 接口方法说明 int Compare(object x, object y) 13
5.13.2 ArrayList.Sort (IComparer) 方法 13
5.14.1 接口方法override int Compare(T x, T y)说明 14
5.14.2 List.Sort (IComparer) 方法 14
5.15 System.Linq.IGrouping<T> 14
5.16 System.Linq.ILookup<TKey,TElement> 14
5.17 System.Linq.IOrderedEnumerable<T> 14
5.18 System.Linq.IOrderedQueryable 14
5.19 System.Linq.IOrderedQueryable<T> 15
5.20 System.Linq.IQueryable 15
5.21 System.Linq.IQueryable<T> 15
5.22 System.Linq.IQueryProvider 15
6.2.5 OrderByDescending 排序降 17
6.2.12 Union 连接不同集合,自动过滤相同项 19
6.2.13 Concat 连接不同集合,不会自动过滤相同项 19
6.2.14 Intersect 获取不同集合的相同项(交集) 20
6.2.15 Except 从某集合中删除其与另一个集合中相同的项 20
6.2.17 TakeWhile 条件第一次不成立就跳出循环 20
6.2.18 SkipWhile 条件第一次不成立就失效,将后面的数据全取 20
6.3.1 Single 集合中符合条件的唯一元素,浅复本 21
6.3.2 SingleOrDefault 集合中符合条件的唯一元素(没有则返回类型默认值),浅复本 21
6.3.4 FirstOrDefault 集合中的第一个元素(没有则返回类型默认值),浅复本 22
6.3.6 LastOrDefault 集合中的最后一个元素(没有则返回类型默认值),浅复本 22
6.3.7 ElementAt 集合中指定索引的元素,浅复本 22
6.3.8 ElementAtOrDefault 集合中指定索引的元素(没有则返回类型默认值),浅复本 22
6.3.9 Contains 判断集合中是否包含有某一元素 22
6.3.10 Any 判断集合中是否有元素满足某一条件 22
6.3.11 All 判断集合中是否所有元素都满足某一条件 23
6.3.12 SequenceEqual 判断两个集合内容是否相同 23
6.3.13 Count 、LongCount集合中的元素个数 23
6.3.16 Aggregate 根据输入的表达式获取一个聚合值 24
6.3.17 DefaultIfEmpty 查询结果为空则返回默认值,浅复本 24
6.3.18 ToArray 将集合转换为数组,浅复本 24
6.3.19 ToList 将集合转换为List<T>集合,浅复本 25
6.3.20 ToDictionary 将集合转换为<K, V>集合,浅复本 25
LINQ查询结果集
Linq |
System.Collections.Generic.IEnumerable<T> |
Linq to DataSet |
System.Data.EnumerableRowCollection<DataRow> |
Linq to SQL |
System.Linq.IQueryable<T> |
Linq to XML |
System.Collections.Generic.IEnumerable<T> |
System.Array 数组
所有数组都继承于System.Array,数组可以用System.Array建立
数组可以是一维也可以是多维数组。"维数"对应于用来识别每个数组元素的下标个数。维数可以多达 32 维。 数组的每一维都有一个非零的长度。在数组的每一维中,数组元素按下标 0 到该维最高下标值连续排列.数组没有固定大小。数组在创建以后仍可以改变大小。
数组是对象,因此每种数组类型都是一个单独的引用类型。这意味着:
1.数组变量中含有指向数据的指针,这些数据包含元素、秩和长度信息。
2.在将一个数组变量赋值给另一个数组变量时,只有指针进行了复制。
3.两个数组变量只有在具有相同的维数和元素数据类型时,才能看成是同一数据类型的数组变量。
基于System.Array定义数组
System.Array x=System.Array.CreateInstance(typeof(string),7); x.SetValue("4",0); x.SetValue("8",1); x.SetValue("7",2); x.SetValue("1",3); x.SetValue("3",4); x.SetValue("2",5); x.SetValue("5",6); System.Console.WriteLine(x.GetValue(5)); |
使用这种方式声明,只能用SetValue与GetValue方法进行赋值与取值, 不能使用x[i]的方式,也不会有x[i].方法() 出现 |
基于类型定义数组
类型[,] 数组名 = new 类型[该维个数, 该维个数]; |
类型[,] 数组名; 数组名 = new 类型[个数,个数]; |
类型[,] 数组名; 数组名 = new 类型[,] {{{值1, 值2, 值3},{值1, 值2, 值3}}; |
类型[,] 数组名 = {{值1, 值2, 值3},{值1, 值2, 值3}}; 类型[] 数组名 ={{值1, 值2, 值3}; |
数组元素的清空
数组名 = null; |
这时不只数组中的元素数据被清空了,而且数组的元素也被清空了. 如果要再使用该数组,需要用重新指定维中的元素个数. 数组的维结构不能被清除. |
System.Array类静态成员
清空指定数组位置中元素的值 |
Array.Clear(数组名, 从第几个开始, 清除几个) |
把[源数组名]中的数据复制到[目标数组名] |
Array.Copy(源数组名, 目标数组名, 要复制的个数) |
按升序排列.只能对一维数组使用 |
Array.Sort(数组名) |
对数组中的元素的顺序返转. |
Array.Reverse(数组名) |
从前向后在数组中查找指定的值.反回在数组中的位置值,如果没找到返回-1,第一个位置是0. |
i= Array.IndexOf (数组名,要找的内容,开始位置) |
从后向前在数组中查找指定的值.反回在数组中的位置值,如果没找到返回-1,第一个位置是0. |
i = Array.LastIndexOf (数组名,要找的内容,开始位置) |
不用循环填充数组
string[] v = new string[50];
v[0] = "wxwinter";
System.Collections.ArrayList.Repeat(v[0], v.Length).CopyTo(v); |
泛型方法见集合的实例泛型方法
数组类实例成员
属性 |
Rank |
返回数组的维数 |
属性 |
Length |
返回数组中元素的个数. |
方法 |
GetLength(维数) |
返回指定维数中元素的个数.第一维是0 |
扩展方法见集合扩展方法
System.Collections 集合
ArrayList
System.Collections
一个数组型集合,使用的是随顺存储
实例成员
Capacity属性 |
获取或设置 ArrayList 可包含的元素数.当实际元素超过Capacity属性时,Capacity属性会在原来的数值上翻倍 |
Count属性 |
集合中元素的个数 |
int = Add(object) |
将对象添加到集合尾部 |
AddRange(Array/List) |
将 ICollection 的元素添加到 ArrayList 的末尾 |
object = Clone() |
创建 ArrayList 的浅表副本 |
ArrayList =GetRange (index, count) |
源 ArrayList 中元素的子集. 可以看成一个视图,两个集合数据是同步的 |
Insert(i,object) |
将对象插入到集合的指定位置 |
InsertRange (index,Array/List) |
将 ICollection 的元素插入到 ArrayList 的指定索引处 |
Remove(object) |
从集合中移除指定对象 |
RemoveAt(index) |
从集合中移除指定位置处的对象 |
RemoveRange (index,count) |
从 ArrayList 中移除一定范围的元素 |
SetRange (index,Array/List) |
将参数中的集合覆盖到调用该方法的集合的指定位置 |
Reverse() |
返转集合中的对象 |
Sort() |
对集合排序 对象集合见 System.IComparable接口 Sort (IComparer) 方法见 System.Collections.IComparer 接口 |
Clear() |
清除集合中所有元素 |
向后查找 |
Integer=集合名.IndexOf (要找的内容变量,开始找的位置) 从前向后在数组中查找指定的值.反回在数组中的位置值,如果没找到返回-1,第一个位置是0. |
向前查找 |
Integer =集合名. LastIndexOf(要找的内容变量,开始位置) 从后向前在数组中查找.反回在数组中的位置值,如果没找到返回-1 |
访问集合中的成员 |
集合[index] |
静态成员
ArrayList ls2 = ArrayList.FixedSize(ls1) |
ls2的元素允许修改,但不允许添加或移除。 两个集合数据是同步的 |
ArrayList ls2 = ArrayList. ReadOnly(ls1) |
ls2的元素只读。 两个集合数据是同步的 |
List<T>
System.Collections.Generic
System.Collections.Generic.List<System.Windows.Forms.TextBox> jh = new List<TextBox>(); jh.Add(new TextBox()); jh.Add(new TextBox()); jh.Add(new TextBox()); int i = 100;
foreach (System.Windows.Forms.TextBox tp in jh) { i = i + 100; tp.Text =i.ToString(); tp.Left = i; this.Controls.Add(tp); } |
class a { public a(string v) { s = v;} public string s; } //使用 System.Collections.Generic.List<a> jh = new List<a>(); jh.Add(new a("123")); jh.Add(new a("456")); jh.Add(new a("789"));
foreach (a tp in jh) { System.Console.WriteLine(tp.s); } |
除ArrayList方法外
ConvertAll
public List<TOutput> ConvertAll<TOutput> (Converter<T,TOutput> converter)
创建复本
调用委托 System.Converter< TInput,TOutput> public delegate TOutput Converter<TInput, TOutput>(TInput input); 将对象从一种类型转换为另一种类型的方法 |
- 将当前 List 中的元素转换为另一种类型,并返回包含转换后的元素的列表
标准委托 |
public static void Main() { List<string> ls = new List<string>() { "1", "2", "3" };
//System.Converter<string, int> cw=new Converter<string,int>(stringToint); //List<int> li = ls.ConvertAll<int>(cw);
List<int> li= ls.ConvertAll<int>(stringToint);
} public static int stringToint(string s) { return int.Parse(s); } |
匿名方法 |
List<string> ls = new List<string>() { "1", "2", "3" }; List<int> li = ls.ConvertAll<int>(delegate(string s) { return int.Parse(s); }); |
Lambda表达式 |
List<string> ls = new List<string>() { "1", "2", "3" }; List<int> li = ls.ConvertAll<int>(i=>int.Parse(i)); |
集合扩展方法 |
List<string> ls = new List<string>() { "1", "2", "3" }; // System.Collections.Generic.IEnumerable<int> li = ls.Select(i => int.Parse(i)); ; var li = ls.Select(i=>int.Parse(i)); |
- 将当前 List 中的元素值批量修改
static void Main(string[] args) { List<string> ls = new List<string>() { "1", "2", "3" }; List<string> li = ls.ConvertAll<string >(stringAdd); }
public static string stringAdd(string s) { return s+"wxd"; } |
ForEach
public void ForEach ( Action<T> action)
对 List 的每个元素执行指定操作
调用委托 System.Action <T> public delegate void Action<T> (T obj) 对传递给它的对象执行某个操作的方法的委托 |
标准委托 |
static void Main(string[] args) { List<string> ls = new List<string>{"wxd","lzm"};
// System.Action<string> w = new System.Action<string>(wxdPrint); // ls.ForEach(w);
ls.ForEach(wxdPrint);
}
static void wxdPrint(string s) { Console.WriteLine(s); } |
匿名方法 |
List<string> ls = new List<string>{"wxd","lzm"}; ls.ForEach(delegate(string name){ Console.WriteLine(name); }); |
Lambda表达式 |
List<string> ls = new List<string> { "wxd", "lzm" }; ls.ForEach(v=> Console.WriteLine(v)); |
集合扩展方法 |
Find、FindLast、FindIndex、FindLastIndex、Exists、TrueForAll
public T Find (Predicate<T> match)
检索与条件匹配的所有元素,并返回整个 List 中的第一个匹配元素,其中包含与指定谓词所定义的条件相匹配的所有元素;否则为一个空 List
创建复本
FindLast 返回索引值 public T FindLast ( Predicate<T> match)
FindIndex 返回索引值 public int FindIndex ( Predicate<T> match)
FindLastIndex 返回逻辑型 public int FindLastIndex ( Predicate<T> match)
Exists 返回逻辑型 public bool Exists ( Predicate<T> match)
TrueForAll 返回逻辑型,确定是否 List 中的每个元素都与指定的谓词所定义的条件相匹配 public bool TrueForAll ( Predicate<T> match)
调用委托 System.Predicate<T> public delegate bool Predicate<T>(T obj); 定义一组条件并确定指定对象是否符合这些条件的方法 |
标准委托 |
public static void Main() { List<int> ls = new List<int>() { 1, 2, 3 };
//System.Predicate<int> cw = new Predicate<int>(wxdFind); // int a = ls.Find(cw);
int a = ls.Find(wxdFind); } public static bool wxdFind(int v) { bool b = (v >= 2);// 查找条件 return b; } |
匿名方法 |
List<int> ls = new List<int>() { 1, 2, 3 }; int a = ls.Find(delegate(int v) { bool b = (v <= 2); return b; }); |
Lambda表达式 |
List<int> ls = new List<int>() { 1, 2, 3 }; int a = ls.Find(v => v >= 2); |
FindAll
public List<T> FindAll (Predicate<T> match)
检索与条件匹配的所有元素,如果找到,则为一个 List,其中包含与指定谓词所定义的条件相匹配的所有元素;否则为一个空 List
创建复本
调用委托 System.Predicate<T> public delegate bool Predicate<T>(T obj); 定义一组条件并确定指定对象是否符合这些条件的方法 |
标准委托 |
public static void Main() { List<int> ls = new List<int>() { 1, 2, 3 };
// System.Predicate<int> cw = new Predicate<int>(WxdFind); //List<int> li = ls.FindAll(cw);
List<int> li = ls.FindAll(WxdFind); } public static bool WxdFind(int v) { bool b = (v <= 2);// 查找条件 return b; } |
匿名方法 |
List<int> ls = new List<int>() { 1, 2, 3 }; List<int> li = ls.FindAll(delegate(int v) { bool b = (v <= 2);return b; }); |
Lambda表达式 |
List<int> ls = new List<int>() { 1, 2, 3 }; List<int> li = ls.FindAll(v => v <= 2); |
集合扩展方法 |
//以视图形式,不创建复本 List<int> ls = new List<int>() { 1, 2, 3 ,4,5}; //System.Collections.Generic.IEnumerable<int> li = ls.Where(i => i < 3); var li = ls.Where(i => i < 3); |
RemoveAll
public int RemoveAll (Predicate<T> match)
移除与指定条件相匹配的所有元素。
调用委托 System.Predicate<T> public delegate bool Predicate<T>(T obj); 定义一组条件并确定指定对象是否符合这些条件的方法 |
标准委托 |
static void Main(string[] args) { List<int> ls = new List<int>() { 1,2, 2, 3,4,5 };
//System.Predicate<int> cw = new Predicate<int>(WxdRem); //int n = ls.RemoveAll(cw);
int n = ls.RemoveAll(WxdRem); //n为移除的个数 }
public static bool WxdRem(int v) { bool b = (v <= 2);// 条件 return b; } |
匿名方法 |
List<int> ls = new List<int>() { 1,2, 2, 3,4,5 }; int n = ls.RemoveAll(delegate(int v) { bool b = (v <= 2);return b; }); |
Lambda表达式 |
List<int> ls = new List<int>() { 1, 2, 3 }; ls.RemoveAll(v => v<=2 ); |
Sort
public void Sort ( Comparison<T> comparison)
对 List 或它的一部分中的元素进行排序
Sort ()方法见 System.IComparable接口、System.IComparable<T>接口
Sort (IComparer) 方法见 System.Collections.IComparer 接口、System.Collections.Generic.IComparer<T> 接口
调用委托 System.Comparison<T> public delegate int Comparison<T> (T x,T y) 表示比较同一类型的两个对象的方法 x 小于 y 返回小于0的负数 x 等于 y 返回0 x 大于 y 返回大于0的正数 |
标准委托 |
static void Main(string[] args) { List<int> ls = new List<int>{1,3,2,4,5,0,8,1};
// System.Comparison<int> w = new Comparison<int>(wxdSort); // ls.Sort(w);
ls.Sort(wxdSort); }
static int wxdSort(int x,int y) { int v = x - y; return v; //return -v; //升序 } |
匿名方法 |
List<int> ls = new List<int>{1,3,2,4,5,0,8,1}; ls.Sort(delegate(int x, int y) { return x - y; }); |
Lambda表达式 |
List<int> ls = new List<int> { 1, 3, 2, 4, 5, 0, 8, 1 }; ls.Sort((x, y) => y - x); |
集合扩展方法 |
//以视图形式,不创建复本 //不改变原集合的顺序 List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; //System.Collections.Generic.IEnumerable<int> li = ls.OrderBy(i => i); var li = ls.OrderBy(i => i); |
Hashtable
System.Collections
System.Collections.DictionaryEntry 结构 字典键/值对
散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
哈希表使用的是链式存储
哈希表使用键值对的方式来存储
哈希表中,键名不能重复
添加键对 |
实例.Add(键,值); |
查找值 |
bool = 实例.ContainsValue(值) |
查找键 |
bool = 实例.ContainsKey(键) |
移除键对 |
实例.Remove(键) |
清空集合 |
实例..Clear() |
通过键访问值 |
x[键] |
得到所有键集合 |
foreach(object t1 in x.Keys) {System.Console.WriteLine(t1);} |
得到所有值集合 |
foreach(object t2 in x.Values) {System.Console.WriteLine(t2);} |
得到所有键值对集合 |
foreach(object zd in x) { System.Collections.DictionaryEntry obj =(DictionaryEntry)zd; System.Console.WriteLine(obj.Key); System.Console.WriteLine(obj.Value); } |
SortedList
System.Collections
SortedList将ArrayList与Hashtable的功能集成
集合容量 |
实例.Capacity 属性 |
查找键 |
bool = 实例.ContainsKey(键) |
查找值 |
bool = 实例.ContainsValue(值) |
得到索引处值 |
object =实例.GetByIndex(index) |
设置索引处值 |
实例.SetByIndex(3,值) |
通过键访问值 |
实例[键] |
移除键对 |
实例.Remove(键) |
移除索引处键对 |
实例.RemoveAt(index) |
得到所有值集合 |
|
得到所有键值对集合 |
|
得到所有键值对集合 |
SortedList<TKey,TValue>
System.Collections.Generic
//System.IComparable //定义通用的比较方法,由值类型或类实现以创建类型特定的比较方法。 class a : System.IComparable { public a(string va,int le) { s = va; l = le; } public string s; public int l;
//实现System.IComparable.CompareTo public int CompareTo(object obj) { if (object.Equals(this, obj)) { return 0; } else { return 1; } } }
//使用 System.Collections.Generic.SortedList<a, System.Windows.Forms.TextBox> jh=new SortedList<a,TextBox>(); a k1 = new a("123",0); a k2 = new a("456",100); a k3 =new a("789",200);
jh.Add(k1, new TextBox()); jh.Add(k2, new TextBox()); jh.Add(k3, new TextBox());
//值操作 foreach (TextBox tp in jh.Values) { this.Controls.Add(tp); }
//键操作 foreach (a tp in jh.Keys) { tp.s = "ok"; }
//键值对操作 foreach (System.Collections.Generic.KeyValuePair<a, TextBox> tp in jh) { tp.Value.Text = tp.Key.s; tp.Value.Left = tp.Key.l; }
//通过键操作值 jh[k2].Text = "hello"; |
Queue<T>
System.Collections.Generic
class a { public a(string v) { s = v; } public string s; }
//使用 System.Collections.Generic.Queue<a> jh = new Queue<a>();
//入队 jh.Enqueue(new a("a")); jh.Enqueue(new a("b")); jh.Enqueue(new a("c"));
//出队:每执行一次出一个 if (0 != jh.Count) { a obj = jh.Dequeue(); System.Console.WriteLine(obj.s); } |
Stack<T>
System.Collections.Generic
class a { public a(string v) { s = v; } public string s; }
//使用 System.Collections.Generic.Stack<a> jh = new Stack<a>();
//入栈 jh.Push(new a("a")); jh.Push(new a("b")); jh.Push(new a("c"));
//出栈:每执行一次出一个 if (0 != jh.Count) { a obj = jh.Pop(); System.Console.WriteLine(obj.s); } |
LinkedList<T>
System.Collections.Generic
class a { public a(string v) {s = v;} public string s; }
//使用 System.Collections.Generic.LinkedList<a> lb = new LinkedList<a>(); System.Collections.Generic.LinkedListNode<a> p;
void 添加结点() { p = new LinkedListNode<a>(new a("1")); lb.AddFirst(p); lb.AddAfter(lb.First, new a("2")); lb.AddBefore(lb.First, new a("3")); lb.AddLast(new a("4")); lb.AddFirst(new a("5")); }
void 读取头尾结点() { string fs = lb.First.Value.s; string ls = lb.Last.Value.s; System.Console.WriteLine(fs +ls); }
void 下一节点(object sender, EventArgs e) { p = p.Next; if (p == null) { System.Console.WriteLine("到达边界"); } else { System.Console.WriteLine(p.Value.s); } }
void 上一结点() { p = p.Previous; if (p == null) { System.Console.WriteLine("到达边界"); } else { System.Console.WriteLine(p.Value.s); } } |
HashSet<T>
System.Collections.Generic
提供高性能的集运算。集是一组不重复出现且无特定顺序的元素
System.Collections.Generic.HashSet<int> h = new HashSet<int>();
//
h.Add(1); h.Add(1); //不报错 h.Add(1);//不报错 h.Add(2); h.Add(2);//不报错 h.Add(3);
//只显示 //1 //2 //3
foreach (var v in h) { System.Console.WriteLine(v); } |
System.Linq
System.Linq.Enumerable
System.Linq.Queryable
System.Linq.Lookup <TKey,TElement>
System.Linq.Expressions.Expression
public delegate TR lzm<T, TR>(T v1); class Program { static void Main(string[] args) { System.Linq.Expressions.Expression<lzm<int, bool>> ep; ep = le => le > 123; } }
|
接口
IEnumerable 、IEnumerator
System.Collections
正常使用
定义: public class 集合 : System.Collections.CollectionBase, System.Collections.IEnumerable { //属性访问器 成员 this[int index] { get{ return (成员)List[index] ; } }
//添加成员 public int Add(成员 v) { return List.Add(v);}
//实现GetEnumerator接口 public new System.Collections.IEnumerator GetEnumerator() { 迭代器 d = new 迭代器(this); return d; } //--------以下为迭代器类------------- //迭代器子类 public class 迭代器 : System.Collections.IEnumerator { int index = -1; //索引用 集合 jh;
public 迭代器(集合 v) //构造函数 { jh = v; }
public void Reset() //重新初始化索引 {index = -1;}
public object Current //返回当前索引所指的对象 { get{return jh.List[index];} }
public bool MoveNext() //将索引指针向下移动一位 { if (index < jh.List.Count-1) { index = index + 1; return true; } return false; } } //--------以下为成员类------------- //迭代器中的数据成员 public class 成员 { public string a;} } |
使用 集合.成员 s1 = new 集合.成员(); 集合.成员 s2 = new 集合.成员(); s1.a = "wxd"; s2.a = "lzm";
集合 j = new 集合();
j.Add(s1); j.Add(s2);
//第一种方法:显示使用 System.Collections.IEnumerator ee = j.GetEnumerator(); while (ee.MoveNext()) { 集合.成员 temp = ( 集合.成员)ee.Current; System.Console.WriteLine(temp.a ); }
//第二种方法:隐式使用 foreach (集合.成员 bb in j) { System.Console.WriteLine(bb.a); } |
C#的 yield
当编译器检测到迭代器时,它将自动生成 IEnumerable 或 IEnumerable 接口的 Current、MoveNext 和 Dispose 方法
省去了写System.Collections.IEnumerator的代码
yield return expression1; yield return expression2; yield return expression3; yield break; //将终止迭代,后面的迭代将不输出 yield return expression4; |
创建 public class wxd : System.Collections.IEnumerable { string[] v = { "a", "b", "c", "d", "e", "f", "g" };
public System.Collections.IEnumerator GetEnumerator() { for (int i = 0; i < v.Length; i++) { yield return v[i]; } yield return "wxd"; yield return "lzm"; } } |
使用 wxd x = new wxd();
//第一种方法:显示使用 System.Collections.IEnumerator ee = x.GetEnumerator(); while (ee.MoveNext()) { string temp = (string)ee.Current; System.Console.WriteLine(temp); }
//第二种方法:隐式使用 foreach (string v in x) { System.Console.WriteLine(v); } |
结果 a b c d e f g wxd lzm |
IEnumerable <T>
System.Collections.Generic
公开枚举数,该枚举数支持在指定类型的集合上进行简单迭代。
IEnumerator <T>
System.Collections.Generic
支持在泛型集合上进行简单迭代。
ICollection
System.Collections
ICollection 接口是 System.Collections 命名空间中类的基接口。
ICollection 接口扩展 IEnumerable;IDictionary 和 IList 则是扩展 ICollection 的更为专用的接口。IDictionary 实现是键/值对的集合,如 Hashtable 类。IList 实现是值的集合,其成员可通过索引访问,如 ArrayList 类。
某些集合(如 Queue 类和 Stack 类)限制对其元素的访问,它们直接实现 ICollection 接口。
如果 IDictionary 接口和 IList 接口都不能满足所需集合的要求,则从 ICollection 接口派生新集合类以提高灵活性。
ICollection <T>
System.Collections.Generic
定义操作泛型集合的方法。
IList
System.Collections
IList 是 ICollection 接口的子代,并且是所有非泛型列表的基接口。IList 实现有三种类别:只读、固定大小和可变大小。无法修改只读 IList。固定大小的 IList 不允许添加或移除元素,但允许修改现有元素。可变大小的 IList 允许添加、移除和修改元素。
IList <T>
System.Collections.Generic
表示可按照索引单独访问的一组对象。
IEqualityComparer
System.Collections
对象的相等比较
IEqualityComparer <T>
System.Collections.Generic
定义方法以支持对象的相等比较。
IDictionary
System.Collections
键/值对基接口
IDictionary <TKey,TValue>
System.Collections.Generic
表示键/值对的泛型集合。
IDictionaryEnumerator
System.Collections
枚举字典的元素
IComparer
System.Collections
比较两个对象的方法
接口方法说明 int Compare(object x, object y)
int Compare(object x, object y) 方法的返回值 小于零 : x小于 y 零 : x等于y 大于零 : x大于 y。 |
ArrayList.Sort (IComparer) 方法
class Program { static void Main(string[] args) { ArrayList ls = new ArrayList() { new wxd { value = 4 }, new wxd { value = 2 }, new wxd { value = 1 }, new wxd { value = 3 } }; ls.Sort(new wxd()); } }
class wxd : System.Collections.IComparer { public int value; public int Compare(object x, object y) { int v = ((wxd)x).value - ((wxd)y).value; return v; } } |
IComparer <T>
System.Collections.Generic
定义类型为比较两个对象而实现的方法。
接口方法override int Compare(T x, T y)说明
override int Compare(T x, T y) 方法的返回值 小于零 : x小于 y 零 : x等于y 大于零 : x大于 y。 |
List.Sort (IComparer) 方法
class Program { static void Main(string[] args) { List<wxd> ls = new List<wxd> { new wxd { value = 4 }, new wxd { value = 2 }, new wxd { value = 1 }, new wxd { value = 3 } }; ls.Sort(new wxd()); } }
class wxd : System.Collections.Generic.Comparer<wxd> { public int value; public override int Compare(wxd x, wxd y) { int v = x.value - y.value; return v; } } |
System.Linq.IGrouping<T>
System.Linq.ILookup<TKey,TElement>
System.Linq.IOrderedEnumerable<T>
System.Linq.IOrderedQueryable
System.Linq.IOrderedQueryable<T>
System.Linq.IQueryable
System.Linq.IQueryable<T>
System.Linq.IQueryProvider
集合扩展方法
集合扩展方法的实现:一个Where的例子
public class a { public int ID { get; set; } public string Name { get; set; } public static void Main() { List<a> list = new List<a> { new a { ID = 1, Name = "wxd" }, new a { ID = 2, Name = "lzm" }, new a { ID = 3, Name = "wxwinter" } };
var l1 = list.WxdWhere(le => le.Name == "lzm");
// 上面的(Lambda表达式)等同于下面的(匿名方法)
IEnumerable<a> l2 = list.WxdWhere(delegate(a le) { return le.Name == "lzm"; });
//与调用系统Where一样 var l3 = list.Where(le => le.Name == "lzm"); }
}
public static class e { // 相关委托 public delegate TResult Func<T, TResult>(T arg);
//相关Where扩展方法 //Func<TSource, bool>:接受一个类型为TSource的参数 //Func<TSource, bool>:某个需要满足的条件,返回bool值 public static IEnumerable<TSource> WxdWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { foreach (TSource item in source) { if (predicate(item)) { yield return item; } } } } |
延迟类
1.须引用System.Core
2.对所有的集合者适用
3.最好用var对象存值
4.可以连用
var li = ls.OrderBy(i => i).Take(5); 表示排序后的前5个 |
5.使用System.Func委托
System.Func<TResult> System.Func<T,TResult> System.Func<T1,T2,TResult> System.Func<T1,T2,T3,TResult> System.Func<T1,T2,T3,T4,TResult> |
6.只是视图,不创建复本
Select 选择
与ConvertAll 不一样,该方法以视图形式反回集合,不创建复本
Lambda表达式 |
List<string> ls = new List<string>() { "1", "2", "3" }; // System.Collections.Generic.IEnumerable<int> li = ls.Select(i => int.Parse(i)); ; var li = ls.Select(i=>int.Parse(i)); |
标准委托 |
static void Main(string[] args) { List<string> ls = new List<string>() { "1", "2", "3" }; var li = ls.Select<string,string>(stringAdd); }
public static string stringAdd(string s) { return s+"wxd"; } |
匿名方法 |
List<string> ls = new List<string>() { "1", "2", "3" }; var li = ls.Select<string, int>(delegate(string s) { return int.Parse(s); }); |
Linq同类功能 |
List<string> ls = new List<string>() { "1", "2", "3" }; var li = from temp in ls select temp; |
SelectMany 选择
Lambda表达式 |
List<string> ls = new List<string>() { "wxd/1", "lzm/2", "wxwinter/3" }; var li = ls.SelectMany(p => p.Split('/')); foreach (var s in li) { Console.WriteLine(s); } |
对应Select效果 |
var ll = ls.Select(p => p.Split('/')); foreach (var s in ll) { foreach (var ss in s) { Console.WriteLine(ss); } } |
Where 条件
与FindAll不一样,该方法以视图形式反回集合,不创建复本
List<int> ls = new List<int>() { 1, 2, 3, 4, 5 }; var li = ls.Where(i => i < 3); //li中此时只有1,2 ls[0] = 333; //1已改为333,li中此时只有2 |
Lambda表达式 |
//以视图形式,不创建复本 List<int> ls = new List<int>() { 1, 2, 3 ,4,5}; //System.Collections.Generic.IEnumerable<int> li = ls.Where(i => i < 3); var li = ls.Where(i => i < 3); |
标准委托 |
static void Main(string[] args) { List<int> ls = new List<int>() { 1, 2, 3, 4, 5 }; // System.Func<int, bool> ww = new Func<int, bool>(w); // var li = ls.Where(ww); var li = ls.Where(w); }
public static bool w(int v) { return v<3; } |
匿名方法 |
List<int> ls = new List<int>() { 1, 2, 3, 4, 5 };
var li = ls.Where(delegate(int v){return v<3;}); |
Linq同类功能 |
List<int> ls = new List<int>() { 1, 2, 3, 4, 5 }; var li = from temp in ls where temp< 3 select temp; |
OrderBy 排序升
与Sort不一样,以视图形式,不创建复本,不改变原集合的顺序
List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; var li = ls.OrderBy(i => i); //---- ls[1] = 6666; ls.Add(-5); //---li中的顺序已重新排列 |
Lambda表达式 |
//以视图形式,不创建复本 //不改变原集合的顺序 List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; //System.Collections.Generic.IEnumerable<int> li = ls.OrderBy(i => i); var li = ls.OrderBy(i => i); |
标准委托 |
static void Main(string[] args) { List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; var li = ls.OrderBy<int,int >(w ); }
public static int w(int i) { return -i; //降序 } |
匿名方法 |
List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; //var li = ls.OrderBy<int, int>(delegate(int i) { return -i; }); var li = ls.OrderBy(delegate(int i) { return -i; }) |
Linq同类功能 |
List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; var li = from temp in ls orderby temp select temp; |
OrderByDescending 排序降
匿名方法 |
List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; var li = ls.OrderByDescending(delegate(int i) { return i; }); |
Lambda表达式 |
List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; var li = ls.OrderByDescending(i => i); |
OrderBy模拟 |
List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; var li = ls.OrderBy(delegate(int i) { return -i; }); |
Linq同类功能 |
List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; var li = from temp in ls orderby temp descending select temp; |
GroupBy 分组
该方法分组结果集合
System.Collections.Generic.IEnumerable<System.Linq.IGrouping<TKey,TElement>>
Lambda表达式 |
string[] wxd = { "Java", "C#", "C++", "Delphi", "VB.net", "VC.net", "C++ Builder", "Kylix", "Perl", "Python" };
var query = wxd.GroupBy(p => p.Length);
foreach (var item in query) { Console.WriteLine("长度 {0}", item.Key); foreach (var val in item) { Console.WriteLine(val); } } |
Linq同类功能 |
string[] wxd = { "Java", "C#", "C++", "Delphi", "VB.net", "VC.net", "C++ Builder", "Kylix", "Perl", "Python" };
var query = from item in wxd group item by item.Length into lengthGroups select lengthGroups; |
Join 联合查询
Lambda表达式 |
static void Main(string[] args) { List<T1> ls1 = new List<T1> { new T1 { Name = "a", Value = 1 }, new T1 { Name = "b", Value = 2 }, new T1 { Name = "c", Value = 3 } }; List<T2> ls2 = new List<T2> { new T2 { ID = "a", bak = "hello" }, new T2 { ID = "a", bak = "wxwinter" }, new T2 { ID = "c", bak = "lzm" }, };
//返回一个新的匿名类的集合 var li=ls1.Join(ls2,temp1=>temp1.Name,temp2=>temp2.ID,(temp1,temp2)=>new { temp1.Name, temp1.Value, temp2.ID, temp2.bak });
foreach (var s in li) { Console.WriteLine("{0}-{1}-{2}-{3}", s.Name, s.ID, s.Value, s.bak); } } }
public class T1 { public string Name; public int Value; } public class T2 { public string ID; public string bak; } |
Linq同类功能 |
//返回一个新的匿名类的集合 var li = from temp1 in ls1 join temp2 in ls2 on temp1.Name equals temp2.ID select new { temp1.Name, temp1.Value, temp2.ID, temp2.bak }; |
GroupJoin
Lambda表达式 |
static void Main(string[] args) { List<T1> ls1 = new List<T1> { new T1 { Name = "a", Value = 1 }, new T1 { Name = "b", Value = 2 }, new T1 { Name = "c", Value = 3 } }; List<T2> ls2 = new List<T2> { new T2 { ID = "a", bak = "hello" }, new T2 { ID = "a", bak = "wxwinter" }, new T2 { ID = "c", bak = "lzm" }, };
//返回一个新的匿名类的集合 var li = ls1.GroupJoin(ls2, temp1 => temp1.Name, temp2 => temp2.ID, (temp1, temp2) => new { temp1.Name, temp1.Value, 个数 = temp2.Count() }); foreach (var s in li) { Console.WriteLine("Name :{0},共有:{1}",s.Name,s.个数.ToString()); }
} }
public class T1 { public string Name; public int Value; } public class T2 { public string ID; public string bak; } |
Linq同类功能 |
//返回一个新的匿名类的集合 var li = from temp1 in ls1 join temp2 in ls2 on temp1.Name equals temp2.ID into newtab select new { temp1.Name, temp1.Value, 个数 = newtab.Count() }; |
Take 获取集合的前n个元素
//以视图形式,不创建复本
List<int> ls = new List<int>() { 1, 3, 2, 4, 5, 0, 8, 1 }; var li = ls.Take(5); //li[1, 3, 2, 4, 5]
ls.Insert(0, 999); //li[999,1, 3, 2, 4] |
Skip 跳过集合的前n个元素
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,50 }; var li = ls.Skip(5); |
Distinct 过滤集合中的相同项
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1 }; var li = ls.Distinct(); |
Union 连接不同集合,自动过滤相同项
List<int> ls1 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1 }; List<int> ls2 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,100,200,100,300 };
var li = ls1.Union(ls2); |
Concat 连接不同集合,不会自动过滤相同项
List<int> ls1 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1 }; List<int> ls2 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,100,200,100,300 };
var li = ls1.Concat(ls2); |
Intersect 获取不同集合的相同项(交集)
List<int> ls1 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,50 }; List<int> ls2 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,100,200,100,300 };
var li = ls1.Intersect(ls2); |
Except 从某集合中删除其与另一个集合中相同的项
List<int> ls1 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,50 }; List<int> ls2 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,100,200,100,300 };
var li = ls1.Except(ls2); |
Reverse 反转集合
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,50 };
ls.Reverse(); |
TakeWhile 条件第一次不成立就跳出循环
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1,50 }; var li =ls.TakeWhile(p=>p<4); |
SkipWhile 条件第一次不成立就失效,将后面的数据全取
List<int> ls = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8,9 ,1,2,3}; var li =ls.SkipWhile(p=>p<=3); |
Cast 将集合转换为强类型集合
ArrayList ls1 = new ArrayList {"a","b","1" };
// ArrayList ls1 = new ArrayList { "a", "b", 1 }; //下面的转换会报错
// List<string > ls2 = (List<string >)ls1; //编译会报错
// List<string> ls3 = (List<string>)ls1.Cast<string>(); //运行会报错
var ls4 = ls1.Cast<string >();
List<string> ls5 = ls1.Cast<string>().ToList<string>(); |
OfType 过滤集合中的指定类型
ArrayList ls1 = new ArrayList {"a","b","c",1 }; var ls4 = ls1.OfType<string>().Cast<string >();
ls1[0] = 345;
foreach (object s in ls4) { System.Console.WriteLine(s); } |
不延迟(浅复本)
Single 集合中符合条件的唯一元素,浅复本
得到的是复本
集合中没有会报错
集合中有两个以上会报错
List<int> ls2 = new List<int>() { 1, 3, 2, 2, 5, 2, 8 };
var v = ls2.Single(p => p==1); //如果集合中没有,或有两个以上会报错, |
SingleOrDefault 集合中符合条件的唯一元素(没有则返回类型默认值),浅复本
得到的是复本
集合中没有则返回类型默认值
集合中有两个以上会报错
List<int> ls2 = new List<int>() { 1, 3, 2, 2, 5, 2, 8 };
var v = ls2.SingleOrDefault(p => p == 1); //集合中有两个以上会报错,集合中没有则返回类型默认值 |
First 集合的第一个元素,浅复本
得到的是复本
集合中没有会报错
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8 };
var o = ls.First(); //第一
var o1 = ls.First(p=>p>2); //第一个大于2的 |
FirstOrDefault 集合中的第一个元素(没有则返回类型默认值),浅复本
得到的是复本
集合中没有则返回类型默认值
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8 };
var o = ls.FirstOrDefault(); //第一个
var o1 = ls.FirstOrDefault(p => p > 2); //第一个大于2的 |
Last 集合中的最后一个元素,浅复本
得到的是复本
集合中没有会报错
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8,1 };
var o = ls.Last(); //最后一个
var o1 = ls.Last(p => p > 2); //最后一个大于2的 |
LastOrDefault 集合中的最后一个元素(没有则返回类型默认值),浅复本
得到的是复本
集合中没有则返回类型默认值
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8,1 };
var o = ls.LastOrDefault(); //最后一个
var o1 = ls.LastOrDefault(p => p > 2); //最后一个大于2的 |
ElementAt 集合中指定索引的元素,浅复本
得到的是复本
集合中没有会报错
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8,1 }; var o = ls.ElementAt(1); |
ElementAtOrDefault 集合中指定索引的元素(没有则返回类型默认值),浅复本
得到的是复本
集合中没有则返回类型默认值
List<int> ls = new List<int>() { 1, 3, 2, 2, 5, 2, 8,1 }; var o = ls.ElementAtOrDefault(100); |
Contains 判断集合中是否包含有某一元素
public class a { static void Main(string[] args) { List<T2> ls2 = new List<T2> { new T2 { ID = "a", bak = "hello" }, new T2 { ID = "a", bak = "wxwinter" }, new T2 { ID = "c", bak = "lzm" }, }; T2 obj = new T2() { bak = "sss", ID = "ok" }; ls2.Add(obj); bool b = ls2.Contains(obj); //true 更多肉容见对像比效 } }
public class T2 { public string ID; public string bak; } |
Any 判断集合中是否有元素满足某一条件
public class a { static void Main(string[] args) { List<T2> ls2 = new List<T2> { new T2 { ID = "a", bak = "hello" }, new T2 { ID = "a", bak = "wxwinter" }, new T2 { ID = "c", bak = "lzm" }, }; bool b1 = ls2.Any(p => p.bak.Contains("ell") ); //true bool b2 = ls2.Any(p => p.ID=="a" ); //true
} }
public class T2 { public string ID; public string bak; } |
All 判断集合中是否所有元素都满足某一条件
public class a { static void Main(string[] args) { List<T2> ls2 = new List<T2> { new T2 { ID = "a", bak = "hello" }, new T2 { ID = "a", bak = "wxwinter" }, new T2 { ID = "c", bak = "lzm" }, }; bool b1 = ls2.All(p => p.bak.Contains("e") );//false bool b2 = ls2.All(p => p.ID.Length ==1 ); //true
} }
public class T2 { public string ID; public string bak; } |
SequenceEqual 判断两个集合内容是否相同
List<int> ls1 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1 }; List<int> ls2 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1 };
bool b1 = ls2.SequenceEqual(ls1); //true |
Count 、LongCount集合中的元素个数
List<int> ls2 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 1 };
int b1 = ls2.Count(p => p < 3); //5 int b2 = ls2.Count(); //8 |
Average 、Sum集合平均值求和
List<int> ls3 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 2 };
var b1 = ls3.Average(); //3.125
var b2 = ls3.Sum(); //25 |
static void Main(string[] args) { List<T1> ls1 = new List<T1> { new T1 { Name = "a", Value = 1 }, new T1 { Name = "b", Value = 2 }, new T1 { Name = "c", Value = 4 } };
var b1 = ls1.Average(p=>p.Value); //2.33333333333333
var b2 = ls1.Sum(p=>p.Value); //7 } }
public class T1 { public string Name; public int Value; } |
Max、Min 集合最大值,最小值
List<int> ls3 = new List<int>() { 1, 3, 2, 2, 5, 2, 8, 2 };
var b1 = ls3.Min(); //1
var b2 = ls3.Max(); //8 |
public class a { static void Main(string[] args) { List<T1> ls1 = new List<T1> { new T1 { Name = "a", Value = 1 }, new T1 { Name = "b", Value = 2 }, new T1 { Name = "c", Value = 4 } };
var b1 = ls1.Min(p=>p.Value); //1
var b2 = ls1.Max(p=>p.Value); //4 } }
public class T1 { public string Name; public int Value; } |
Aggregate 根据输入的表达式获取一个聚合值
List<int> ls3 = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9,10 };
var b1 = ls3.Aggregate((x, y) => x + y );//55 累加 var b2 = ls3.Aggregate((x, y) => x * y);//3628800 累乘 |
public class a {
static void Main(string[] args) { List<T1> ls1 = new List<T1> { new T1 { Name = "a", Value = 1 }, new T1 { Name = "b", Value = 2 }, new T1 { Name = "c", Value = 4 } };
var b3 = ls1.Aggregate<T1>((x, y) => new T1 { Value = x.Value + y.Value });
System.Console.WriteLine(b3.Value); //7
} }
public class T1 { public string Name; public int Value; } |
DefaultIfEmpty 查询结果为空则返回默认值,浅复本
如果集合是的无素为空(count==0),就向集合中插入一个默认元素
List<string > ls3 = new List<string >() { "wxd","lzm","wxwinter" ,"wxd"};
var ls4 = ls3.Where(p => p == "ok").DefaultIfEmpty("not"); ;
//如果不存在返回给集合一个自定义的对象 |
ToArray 将集合转换为数组,浅复本
List<string > ls3 = new List<string >() { "wxd","lzm","wxwinter" ,"wxd"}; string[] ss = ls3.ToArray(); |
ToList 将集合转换为List<T>集合,浅复本
List<string > ls3 = new List<string >() { "wxd","lzm","wxwinter" ,"wxd"};
List<string> ss = ls3.ToList();
ls3[0] = "kk"; //不影响 ss 集合 |
List<string > ls3 = new List<string >() { "wxd","lzm","wxwinter" ,"wxd"};
var ss = ls3.Select(p=>p);
ls3[0] = "kk"; //影响 ss 集合 |
ToDictionary 将集合转换为<K, V>集合,浅复本
public class a { static void Main(string[] args) { List<T1> ls1 = new List<T1> { new T1 { Name = "a", Value = 1 }, new T1 { Name = "b", Value = 2 }, new T1 { Name = "c", Value = 4 } }; System.Collections.Generic.Dictionary<string, T1> dd = ls1.ToDictionary(p => p.Name);
var d = ls1.ToDictionary(p => p.Name); //如果集合中有值相同的Name,将报错 //指定对象为键,原集合中的对象为值
foreach (var s in dd) { System.Console.WriteLine(s); } }
}
public class T1 { public string Name; public int Value; }
|
末整理方法
AsQueryable
Lambda表达式
Lambda表达式是委托的一种实现方式。与匿名方法类似。
格式
声名参数 => 分隔符 表达式
表达式的结果为委托返回值 |
p => p + 1 p => p < 4 (int p) => p +1 (p1,p2) => p1 + p2 |
例1(比效)
Lambda表达式 |
public delegate TR lzm<T, TR>(T v1);
class a { public void f(lzm<int, bool> func) { bool b= func(100); if (b) { System.Console.WriteLine("v大于100"); } else { System.Console.WriteLine("v小于100"); } } }
class Program { static void Main(string[] args) { a obj = new a(); int v = 70; obj.f(p => v > p); obj.f((int p) => v > p); //显示类型 } } |
委托 |
public delegate TR lzm<T, TR>(T v1);
class a { public void f(lzm<int, bool> func) { bool b= func(100); if (b) { System.Console.WriteLine("v大于100"); } else { System.Console.WriteLine("v小于100"); } } }
class Program { static void Main(string[] args) { a obj = new a(); obj.f(w); }
public static bool w(int v1) { int v = 70; bool b = v > v1;
return b; }
} |
匿名方法 |
public delegate TR lzm<T, TR>(T v1);
class a { public void f(lzm<int, bool> func) { bool b= func(100); if (b) { System.Console.WriteLine("v大于100"); } else { System.Console.WriteLine("v小于100"); } } }
class Program { static void Main(string[] args) { a obj = new a(); obj.f( delegate(int v1) {return 70 > v1; }); Console.Read(); } } |
例2(多参)
public delegate T lzm<T1, T2, T>(T1 v1, T2 v2);
class a { public void f(lzm<int, int, int> func,int x,int y) { int b = func(x, y); System.Console.WriteLine(b); } } class Program { static void Main(string[] args) { a obj = new a(); obj.f((v1, v2) => v1 - v2,100,200); Console.Read(); } } |
例3(list.Where)
public class a { public int ID { get; set; } public string Name { get; set; } public static void Main() { List<a> list = new List<a> { new a { ID = 1, Name = "wxd" }, new a { ID = 2, Name = "lzm" }, new a { ID = 3, Name = "wxwinter" } };
var l1 = list.WxdWhere(le => le.Name == "lzm");
// 上面的(Lambda表达式)等同于下面的(匿名方法)
IEnumerable<a> l2 = list.WxdWhere(delegate(a le) { return le.Name == "lzm"; });
//与调用系统Where一样 var l3 = list.Where(le => le.Name == "lzm"); }
}
public static class e { // 相关委托 public delegate TResult Func<T, TResult>(T arg);
//相关Where扩展方法 //Func<TSource, bool>:接受一个类型为TSource的参数 //Func<TSource, bool>:某个需要满足的条件,返回bool值 public static IEnumerable<TSource> WxdWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { foreach (TSource item in source) { if (predicate(item)) { yield return item; } } } } |
Lambda表达式中Lifting
public class a { static void Main(string[] args) { List<Func<int>> list = new List<Func<int>>();
for (int i = 0; i < 3; i++) { //int temp = i; // list.Add(() => temp); // 1,2,3 这个temp,就称为lifting。lift是美语中的电梯,翻译为梯子或垫脚石,比较妥帖
list.Add(() => i); //3,3,3 }
foreach (var item in list) { Console.WriteLine(item()); } } } |
所盼望输出,0,1,2,而实际结果是3,3,3。 两个原因。 第一,在for循环中,只能有一个 i 变量。即再第一次循环时,i 的地址就分配好了,不会因为循环次数的多少而发生任何改变,其改变的只能是里面装载的值。
第二,lambda表达式在构造时,传进去的是变量的地址,而不是具体值。只有当真正执行这个lambda表达式时,才会去确定它的值。这就是为什么上面的例子中,其结果均为3。(for循环在最后,又给 i 加了1)
在for循环中,定义一临时变量temp存储 i的值即可。因为编译器会对该临时变量重新分配内存,这样,每次循环,都重新分配新的内存,就不会有这个问题
|
QuerySyntax 查询语法
-
查询句法是使用标准的LINQ查询运算符来表达查询时一个方便的声明式简化写法
每个查询表达式的句法从from子句开始,以select或group子句结束
结果集合 = from 临时变量 in 要查询的集合 [....] select 返回内容;
[结果集合]的类型与[select 返回内容]的类型一样 [....] 其它关键字 |
- 查询句法返回的类型是 System.Collections.IEnumerable 、 System.Collections.Generic.IEnumerable<T>
public class a { static void Main(string[] args) { List<T> ls = new List<T> { new T { Name = "a", Value = 1 }, new T { Name = "b", Value = 2 }, new T { Name = "c", Value = 3 }, };
var l1 = from temp in ls select temp;
var l2 = from temp in ls select "姓名:" + temp.Name ;
var l3 = from temp in ls where temp.Value <= 2 select temp;
System.Collections.IEnumerable l4 = from temp in ls where temp.Value <= 2 select temp;
System.Collections.Generic.IEnumerable<T> l5 =from temp in ls where temp.Value <= 2 select temp; }
}
public class T { public string Name; public int Value; } |
3.结果集合以视图方式返回,源集合的内容改变后,会反映到结果集合上。在Select时New全新的对像也是这种情况,因为[结果集合]是动态的,每次访问都按查询句重新生成
public class a { static void Main(string[] args) { List<T> ls = new List<T> { new T { Name = "a", Value = 1 }, new T { Name = "b", Value = 2 }, new T { Name = "c", Value = 3 }, }; var l3 = from temp in ls select new T2 { x=temp.Name , y=temp.Value , z=000};
foreach (var s in l3) { Console.WriteLine(s.x + s.y + s.z); }
ls[0].Name = "wxd";
foreach (var s in l3) { Console.WriteLine(s.x + s.y + s.z);} System.Console.Read(); } }
public class T { public string Name; public int Value; } public class T2 { public string x; public int y; public int z; } |
-
如果不要延迟查询运算,而是要对它们立刻就执行运算,
可以使用内置的ToList() 和ToArray() 运算符来返回一个包括了结果集的List<T>或者数组。
List<int> ls = new List<int>() { 1, 2, 3, 4, 5 };
// var l3 = (from temp in ls select temp); var l3 = (from temp in ls select temp).ToList() ; |
from in select
class Program { static void Main(string[] args) { List<T> ls = new List<T> { new T { Name = "a", Value = 1 }, new T { Name = "b", Value = 2 }, new T { Name = "c", Value = 3 }, }; List<int> li = new List<int> {1,2 };
var l1 = from temp1 in ls from temp2 in li where temp1.Value == temp2 select new { temp1.Name, v = temp2 * 100 }; //返回一个新的匿名类的集合 } }
public class T { public string Name; public int Value; } |
orderby 排序
orderby 字段,字段 descending /ascending
public class a { static void Main(string[] args) { List<T> ls = new List<T> { new T { Name = "a", Value = 1 }, new T { Name = "b", Value = 2 }, new T { Name = "c", Value = 3 }, };
var l1 = (from temp in ls orderby temp.Value, temp.Name select temp);
var l2 = (from temp in ls orderby temp.Value descending select temp);
var l3 = (from temp in ls where temp.Value < 5 orderby temp.Value ascending select temp);
var l4 = (from temp in ls orderby temp.Value ascending where temp.Value < 5 select temp); } }
public class T { public string Name; public int Value; } |
group by into 分组
分组结果集合 = from 临时变量A in 要查询的集合 group 临时变量A by 分组关键字 into 临时变量B select 临时变量B
其中的 into 关键字表示 将前一个查询的结果视为后续查询的生成器,这里是跟 group by 一起使用的。 |
分组结果集合 System.Collections.Generic.IEnumerable<System.Linq.IGrouping<TKey,TElement>>
|
public class a {
static void Main(string[] args) { List<T> ls = new List<T> { new T { Name = "a", Value = 1 }, new T { Name = "b", Value = 2 }, new T { Name = "c", Value = 3 }, new T { Name = "d", Value = 1 }, new T { Name = "e", Value = 3 } };
var l1 = from temp in ls group temp by temp.Value into gp select gp;
var l2 = from temp in ls orderby temp.Name descending //对ls的结果集合排序 group temp by temp.Value into gp orderby gp.Key descending //对组集合排序 select gp;
System.Collections.Generic.IEnumerable<System.Linq.IGrouping<int,T>> l3 = from temp in ls group temp by temp.Value into gp select gp; foreach (var s in l2) { Console.WriteLine("{0}组",s.Key); foreach (var ss in s) { Console.WriteLine(ss.Name); } }
} }
public class T { public string Name; public int Value; }
|
string[] wxd = { "Java", "C#", "C++", "Delphi", "VB.net", "VC.net", "C++ Builder", "Kylix", "Perl", "Python" };
var query = from item in wxd orderby item group item by item.Length into lengthGroups orderby lengthGroups.Key descending select lengthGroups;
foreach (var item in query) { Console.WriteLine("长度 {0}", item.Key); foreach (var val in item) { Console.WriteLine(val); } } |
join in on equals 联合查询
public class a {
static void Main(string[] args) { List<T1> ls1 = new List<T1> { new T1 { Name = "a", Value = 1 }, new T1 { Name = "b", Value = 2 }, new T1 { Name = "c", Value = 3 } }; List<T2> ls2 = new List<T2> { new T2 { ID = "a", bak = "hello" }, new T2 { ID = "a", bak = "wxwinter" }, new T2 { ID = "c", bak = "lzm" }, };
//返回一个新的匿名类的集合 var li = from temp1 in ls1 join temp2 in ls2 on temp1.Name equals temp2.ID select new { temp1.Name, temp1.Value, temp2.ID, temp2.bak }; foreach (var s in li) { Console.WriteLine("{0}-{1}-{2}-{3}",s.Name,s.ID,s.Value,s.bak); } } }
public class T1 { public string Name; public int Value; } public class T2 { public string ID; public string bak; } |
into 汇总
static void Main(string[] args) { List<T1> ls1 = new List<T1> { new T1 { Name = "a", Value = 1 }, new T1 { Name = "b", Value = 2 }, new T1 { Name = "c", Value = 3 } }; List<T2> ls2 = new List<T2> { new T2 { ID = "a", bak = "hello" }, new T2 { ID = "a", bak = "wxwinter" }, new T2 { ID = "c", bak = "lzm" }, };
//返回一个新的匿名类的集合 var li = from temp1 in ls1 join temp2 in ls2 on temp1.Name equals temp2.ID into newtab select new { temp1.Name, temp1.Value, 个数 = newtab.Count() }; foreach (var s in li) { Console.WriteLine("Name :{0},共有:{1}",s.Name,s.个数.ToString()); } } }
public class T1 { public string Name; public int Value; } public class T2 { public string ID; public string bak; } |
DataSource 数据绑定
public class aa { public string a { get; set; }
public string b { get; set; } } |
winform List<aa> ls = new List<aa> { new aa { a = "a", b = "1" }, new aa { a = "b", b = "2" } };
dataGridView1.DataSource = ls; //数据修改会与集合同步 //两个控件指针会同步 comboBox1.DataSource = ls; comboBox1.DisplayMember = "b"; |
aspnet protected void Button1_Click(object sender, EventArgs e) { List<aa> ls = new List<aa> { new aa { a = "a", b = "1" }, new aa { a = "b", b = "2" } }; this.GridView1.DataSource = ls;
DropDownList1.DataSource = ls; DropDownList1.DataTextField = "b"; DropDownList1.DataValueField = "a"; this.DataBind(); } |