在2.0之前的版本中,如果要声明委托,要通过命名方法来实现。而2.0开始引入了匿名方法,在3.0及更高版本中,提供了lambda来取代匿名方法,作为编写内联代码的首选方式。
(一)通过命名方法来声明委托
public void NomalDelegate()
{
PrintName pp = ShowName;
pp( " John " );
}
public void ShowName( string strName)
{
Console.WriteLine( " Hello, " + strName);
}
声名委托,不返回值,带有一个串型参数。创建ShowName方法的委托对象pp,通过pp来代理ShowName方法的全部功能。
这是在2.0之前版本中支持。
(二)通过匿名方法来声明委托
public void AnonymousDelegate()
{
PrintName pp = delegate ( string strName)
{
Console.WriteLine( " Hello, " + strName);
};
pp( " John " );
}
这里省略了ShowName方法,通过匿名方法对这个方法做了抽象,使这个方法没有了意义,但执行相同的功能。
匿名方法提供一种内联代码编写的首选方式。因为是内联的,所以,这里要添加分号,来做了一个表达式的结束。
在2.0中,开始增加了对匿名方法的支持。
(三)通过lambda表达式来创建委托
{
PrintName pp = strName => Console.WriteLine( " Hello, " + strName);
pp( " John " );
}
比较一下匿名方法与lambda表达式。
PrintName p2 = strName => Console.WriteLine( " Hello, " + strName);
匿名方法参数由lambda左边参数列表指定,代码段{}隐藏(对于多条语句的,要添加{},如(a, b) => { Console.WriteLine(a); Console.WriteLine(b); };)。goesto(=>)可以理解为分隔符,用于区分方法参数与方法体。而参数类型string因为匿名类型的原因隐藏(当然,也可以用强类型来指定类型,但须加(),例如(string strName))。对于单参数,()可以省略;对于多个参数,要添加(),如(a,b);对于零个参数,也要添加(),如()。
(四)Lambda表达式解读
(1)x=>x==5
这个表达式实相当于方法
{
if (x == 5 ) return true ;
return false ;
}
它用于返回bool型值。但这个表达是一个委托类型。通过Func<>方法委托来实现。如下:
bool bSign = fun( 5 );
(2)n => n % 2 == 1
这个部分取自以下场景:
int oddNumbers = numbers.Count(n => n % 2 == 1 );
通过以上场景判断,n % 2 == 1相当于:
{
if (n % 2 == 1 ) return true ;
return false ;
}
通过Func委托方法实现:
而 Count 方法有两个重载:
public static int Count < TSource > ( this IEnumerable < TSource > source,Func < TSource, bool > predicate)
这种方法叫做扩展方法。而这个场景应用的就是第二个扩展方法,就是实现IEnumerable泛型接口的数组,来统计用来满足条件n % 2 == 1的元素的个数,而这个参数就是一个Func<TSource, bool>类型的委托实例,就是我们的:
也就是查找奇数的个数。
(3)n => n < 6
还是这个场景:
var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6 );
通过场景分析,可以得到n=>n<6的命名方法:
{
if (n < 6 ) return true ;
return false ;
}
通过Func委托实现:
TakeWhile方法也是扩展方法:
Func < TSource, bool > predicate
)
public static IEnumerable < TSource > TakeWhile < TSource > ( this IEnumerable < TSource > source,
Func < TSource, int , bool > predicate
)
而我们用到的就是第一个,它的功能定义为:只要满足指定的条件,就会返回序列的元素,然后跳过剩余的元素。
所以它返回的是一个Ienumerable泛型接口的泛型集。而上一个例子中的Count返回的则是一个int值。
Console.WriteLine(i);