一、匿名方法、Lambda表达式
1、匿名方法的概念:一个方法没有具体的名称,而只有关键字delegate、方法参数、方法体,这种方法是匿名方法。
匿名方法的好处:将具体方法和委托直接关联到一起,如果我们基于委托只需要一个方法的时候,匿名方法肯定是显得简单。
2. Lambda表达式:在C#3.0出现的。使用这种表达的可以更简练的编写代码块。
CalculatorDelegate cal3 = (int a, int b) => { return a + b; };
CalculatorDelegate cal4 = (a, b) => a - b;
【1】在Lambda表达式中参数类型可以是明确类型,也可以是推断类型。
【2】如果是推断类型,则参数类型可以由编译根据上下文自动推断出来。
【3】运算符=> 读作goes to ,运算符左边输入参数(如果有),右边是表达式或语句块。
【4】表达式两种方式:
(input args)=>表达式
(input args)=>{ 语句1;语句2;语句3....}
【5】Lambda表达式和匿名方法的比较
第一、Lambda表达式本身就是匿名方法。
第二、Lambda表达式允许不指明参数类型,但是匿名方法必须要明确。
第三、Lambda表达式允许单一的表达式或多条语句组成,而匿名方法不允许单一表达式。
二、自定义泛型委托
1.为什要使用泛型委托?普通委托在数据类型的限定上非常严格的。有时候我们需求变化,可能适应不了。
2.泛型委托定义:本质上和泛型方法是非常相似的,泛型委托关联的时候,可以是具体方法、匿名方法、lambda表达式
3.问题引出:仔细研究我们写的泛型委托: public delegate T MyGenericDelegate<T>(T param1, T param2);
试想:如果我们使用4个参数?5个参数?8个参数?按照目前思路,不得不定义很多这种泛型委托!很麻烦!
三、系统泛型委托
针对问题的解决:.NET平台早就为你考虑了这种简单的泛型委托,那就是人家已经定义好了,我们可以直接使用!
两种方式:一种是有返回值Func<args>,一种是没有返回值的Action<args>。
Action<>在多线程中用的非常多。
Func<>在扩展方法中用的非常多。
class LambdaDemo
{
public void Test()
{
//【1】委托关联独立的方法
CalculatorDelegate cal1 = Add;
//【2】委托关联匿名方法
CalculatorDelegate cal2 = delegate (int a, int b)
{
return a - b;
};
//【3】将匿名方法用Lambda表达式简化编写goes to
CalculatorDelegate cal3 = (int a, int b) => { return a + b; };
Console.WriteLine("通过匿名方法计算:20-30=" + cal2(20, 30));
//进一步简化(假如,方法中只有一行代码)
CalculatorDelegate cal4 = (a, b) => a - b;
SayHelloDelegate sayHello = () => "欢迎大家参加常老师主讲的VIP课程";
Console.WriteLine("通过Lambda表达式计算:20-30=" + cal4(20, 30));
}
private int Add(int a, int b)
{
return a + b;
}
//根据委托的使用可以继续增加其他的方法...
}
public delegate int CalculatorDelegate(int a, int b);
public delegate string SayHelloDelegate();
class FunDelegateDemo
{
#region 【1】Func委托的基本使用
public void Test1()
{
//【1】Func关联具体方法
Func<int, int, double> myFunc1 = Add1;
//【2】Func直接使用Lambda表达式
Func<int, int, double> myFunc2 = (a, b) => a + b;
Console.WriteLine("Func的使用:" + myFunc2(10, 20));
}
private double Add1(int a, int b)
{
return a + b;
}
#endregion
#region 【2】Func委托的重要使用
//问题:给定一个数组 { 10, 9, 8, 7, 6, 5, 4, 3, 2 },从数组中指定位置抽取3个数,求和、求积
//思考:我们运算的要求不一样(求和、求积),两种运算可以单独做为方法
public int Sum(int[] nums, int from, int to)
{
int result = 0;
for (int i = from; i <= to; i++)
{
result += nums[i];
}
return result;
}
public int Mul(int[] nums, int from, int to)
{
int result = 1;
for (int i = from; i <= to; i++)
{
result *= nums[i];
}
return result;
}
//还可以继续增加其他的方法...
public void Test2()
{
int[] nums = { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
//【1】普通的方法
int resul1 = Sum(nums, 0, 2);
Console.WriteLine(" 10, 9, 8 求和=" + resul1);
int result2 = Mul(nums, 0, 2);
Console.WriteLine(" 10, 9, 8 求积=" + result2);
}
//使用Func委托,将“运算”本身作为方法参数
public int Operation(Func<int, int, int> method, int[] nums, int from, int to)
{
int result = nums[from]; //把第一个值作为一个基数 from + 1表示下一个值
for (int i = from + 1; i <= to; i++)
{
result = method(result, nums[i]);
}
return result;
}
static int Add2(int a, int b)
{
return a + b;
}
static int Multiply(int a, int b)
{
return a * b;
}
public void Test3()
{
int[] nums = { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
int resul1 = Operation(Add2, nums, 0, 2);
Console.WriteLine(" 10, 9, 8 求和=" + resul1);
int result2 = Operation(Multiply, nums, 0, 2);
Console.WriteLine(" 10, 9, 8 求积=" + result2);
Console.WriteLine("----------------------------------------------");
//【2】将Func作为方法参数,结合Lambda表达式
int resul3 = Operation((a,b)=>a+b, nums, 0, 2);
Console.WriteLine(" 10, 9, 8 求和=" + resul3);
int result4 = Operation((a, b) => a *b, nums, 0, 2);
Console.WriteLine(" 10, 9, 8 求积=" + result4);
}
#endregion
}