我为了更好的理解C#中的委托,、泛型委托、匿名方法和Lambda表达式,我把它们的演变过程通过自己的理写了出来,各位高手要是看到有什么不妥的地方,还望指出。
首先,我从一个C语言中很简单的一个问题开始,比较两个数的大小,并将最大的数以string 型输出
首先来看比较常规的写法:
public delegate string DelegateCompare(int Num1,int Num2); //定义委托
class Compare
{
public static string NumCompare(int Num1, int Num2)
{
return Num1 > Num2 ? Num1.ToString() : Num2.ToString();
}
}
class CompareApplication
{
static void Main()
{
DelegateCompare delegate1 = new DelegateCompare(Compare.NumCompare);
string STR = "最大的数位:" + delegate1(10, 20);
Console.WriteLine(STR);
Console.ReadLine();
}
}
为了精简代码(当然这个理由似乎不够充分),我们决定使用匿名方法,也许这里你并不能看到匿名方法的真正好处,但是,当把.NET方法做为委托参数时或处理时间时,就能看到匿名方法的真正用处。下面是贴过来的代码:
public delegate string DelegateCompare(int Num1,int Num2); //定义委托
class CompareApplication
{
static void Main()
{
DelegateCompare delegate1 = new DelegateCompare(delegate(int Num1, int Num2) {
return Num1 > Num2 ? Num1.ToString() : Num2.ToString();
});
string STR = "最大的数位:" + delegate1(10, 20);
Console.WriteLine(STR);
Console.ReadLine();
}
}
正如你所见到的一样,我把Compare类完全删除了,那比较大小的功能是通过什么完成的了,这就是匿名方法,通过delegate关键字,我们声明了一个没有方法名的方法体。
接下来我有个大胆的想法,将委托声明也去掉,这时就应该用到泛型委托
class CompareApplication
{
static void Main()
{
Func
{
return Num1 > Num2 ? Num1.ToString() : Num2.ToString();
});
string STR = "最大的数位:" + delegate1(10, 20);
Console.WriteLine(STR);
Console.ReadLine();
}
}
在上面的代码中,我将委托的声明全部用Func
public delegate string DelegateCompare(int Num1,int Num2),从委托的声明中我们得知,绑定到该委托的方法必须具有两个int型参数并且其返回值类型为string,那么泛型委托Func
这时,所有的代码都集中在一个函数里了,够精简了,还能不能更加精简了,好,这时候lambda表达式出场了
class CompareApplication
{
static void Main()
{
Func
string STR = "最大的数位:" + delegate1(10, 20);
Console.WriteLine(STR);
Console.ReadLine();
}
}
我们一定能看出来,这里面最重要的就是这句:Func
好了,上面就是我对这些概念的理解。本人是个初学者,还请各位高手多多指教。
补充几点:
只有在 Lambda 有一个输入参数时,括号才是可选的;否则括号是必需的。 两个或更多输入参数由括在括号中的逗号分隔
有时,编译器难于或无法推断输入类型。 如果出现这种情况,您可以按以下示例中所示方式显式指定类型:(int x, string s) => s.Length > x
使用空括号指定零个输入参数:() => SomeMethod()
Lambda 语句与 Lambda 表达式类似,只是语句括在大括号中:
(input parameters) => {statement;}
Lambda 语句的主体可以包含任意数量的语句;但是,实际上通常不会多于两个或三个语句。
delegate void TestDelegate(string s); … TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); }; myDel("Hello");
在编写 Lambda 时,通常不必为输入参数指定类型,因为编译器可以根据 Lambda 主体、基础委托类型以及 C# 语言规范中描述的其他因素推断类型。
Lambda 的一般规则如下:
Lambda 包含的参数数量必须与委托类型包含的参数数量相同。
Lambda 中的每个输入参数必须都能够隐式转换为其对应的委托参数。
Lambda 的返回值(如果有)必须能够隐式转换为委托的返回类型。
请注意,Lambda 表达式本身没有类型,因为常规类型系统没有“Lambda 表达式”这一内部概念。但是,有时会不正式地论及 Lambda 表达式的“类型”。 在这些情况下,类型是指委托类型或 Lambda 表达式所转换为的 Expression 类型。