C#中的委托delegate和Lambda表达式
委托:委托别人去帮我完成某件事情。
自定义委托
自定义委托
AddDelegate AD = new AddDelegate(Add); //获取需要委托的方法详细,参数返回值和定义委托参数返回值都必须一样。 string str = AD.Invoke(5, 2); //执行委托:Invoke或者不写,可以直接使用 AD(5,2) Console.WriteLine(str); //Add方法委托AddDelegate对象帮忙执行,实际上运行的是Add方法内容。 string Add(int a,int b) { return $"两个参数有返回值的普通方法:{a + b}"; } delegate string AddDelegate(int a, int b);//定义委托delegate
泛型委托
AddDelegate<string> AD = A.Add; //简写不需要new,给方法就可以 string str = AD("1", "3"); //调用委托简写,不需要Invoke方法。 Console.WriteLine(str); class A { public static string Add(string a, string b) { return $"两个参数有返回值的普通方法:{a + b}"; } public static string Add(int a, int b) { return a + b +""; } } delegate string AddDelegate<T>(T a, T b);//泛型委托,返回值不能定义泛型,只能定义参数
“协变:out”->”和谐的变”->”很自然的变化”->string->object 小到大
“逆变:in”->”逆常的变”->”不正常的变化”->object->string 大转小
直白的说:out: 输出(作为返回值结果),in:输入(作为参数)
delegate M AddDelegate<in T, in T1,out M>(T a, T1 b);//in进参,外面传进来的参数,默认in可以不写;out出参,做返回值。
系统委托(系统定义好的两个):Action无返回值委托---Func有返回值委托。最后一个参数是返回值,两个委托最多参数只有16种重载
Action<int> a = A.Add;//Action无返回值委托,最多16个参数,无参不写<> a(22);//参数22 Func<int, int ,string> AD = A.Add;//Func有返回值委托,最多16个参数+最后一个是返回值 = 17个参数 string str = AD(1, 3); //返回值是最后一个参数string Console.WriteLine(str); class A { public static void Add(int a) { Console.WriteLine("Action有参无返回值委托"); } public static string Add(int a, int b) { return $"Func有参数有返回值委托的普通方法:{a + b}"; } }
匿名方法的委托
Action<string> AD = new Action<string>(delegate(string str) { Console.WriteLine(str); }); AD("这是一个匿名方法的委托");
Lambda表达式:本质也是一个匿名方法,语法:(参数)=> { 方法体 }
Action<string> AD = str => Console.WriteLine(str); AD("一个参数单个语句的简写,lambda表达式,一个参数可以不写括号");
Action AD = () => Console.WriteLine("无参无返回值"); AD();
Func<string> AD = () => "无参有返回值委托,一条语句,不写return。"; Console.WriteLine(AD());
Func<int,int,string> AD = (int i ,int a) => { Console.WriteLine("如果是一个参数,可以不需要括号,不需要数据类型。"); return $"有参有返回值的委托:{i + a}"; }; Console.WriteLine(AD(5, 2));
系统Lamdba 扩展方法:查询集合返回一个集合。语法:集合名.where(a =>a==条件); a集合里边装的内容:如果集合里边装的字符串a表示字符串,如果集合里边装的Int则a表示Int
List<string> ilist = new List<string>() { "陈一", "小二", "张三", "李四", "王五", "赵六", "西瓜", "香瓜", "木瓜", "香菜", "香逗" }; Console.Write("请输入你需要查询的内容:"); string str = Console.ReadLine();//接收用户输入的值 //lamdba查询内存集合的写法 List<string> rsult = ilist.Where(a => a.Contains(str)).ToList();//a.Contains(str)模糊查询,查询集合返回一个集合 rsult.ForEach(item => { Console.WriteLine(item); }); Console.WriteLine("foreach内部实现原理也是lamdba"); //一般的foreach遍历 foreach (string itme in rsult) { Console.WriteLine(itme); } //做一个精准匹配返回单个值 First()或者是FirstorDefault(); //string str1 = ilist.Where(a => a == str).First();//找不到就报错 //Console.WriteLine("First精准匹配的返回值:" + str1); string str2 = ilist.Where(a => a == str).FirstOrDefault(); //找不到就赋空值,把a == str改为a.Contains(str)模糊查询,只要一个匹配就返回 Console.WriteLine("FirstOrDefault的返回值:" + str2); //精准查询,要一模一样才会返回