namespace DelegateDemo1
{
class Program
{
static void Main(string[] args)
{
Func<int, int, int> fun = delegate(int x, int y) { return x + y; };
Func<int, int, int> fun1 = delegate(int x, int y) { return x - y; };
int result4 = fun(8, 10);
int result5 = fun1(12, 8);
Console.WriteLine("预定义的委托输出{0},{1}", result4, result5);
Console.ReadLine();
}
}
}
看看是不是在原来的基础上大幅度减少了代码量,肿么办,是否代码量已经减少到极致了?
lambda表达式
其实对于委托的定义还可以进一步简化,那就是使用lambda表达式,lambda表达式的定义是(参数列表)=>{方法体},=>读作goes to。lambda表达式对参数列表和方法表达式的精简达到极致,对于上面的例子,用λ表达式可以省略掉匿名委托的关键字和参数类型,系统可以进行类型推断,不影响运行,其简化的代码如下。对.net 1.0,2.0最传统的委托定义和使用,是一个巨大的简化,它剔除了所有多余的语句达到极致。
namespace DelegateDemo1
{
class Program
{
static void Main(string[] args)
{
Func<int, int, int> fun = (x, y) => x + y;
Func<int, int, int> fun1 = (x, y) => x - y;
int result4 = fun(8, 10);
int result5 = fun1(12, 8);
Console.WriteLine("预定义的委托输出{0},{1}", result4, result5);
Console.ReadLine();
}
}
}
委托链
前面讲过,委托在本质上仍然是一个类,我们用delegate关键字声明的所有委托都继承自System.MulticastDelegate。后者又是继承自System.Delegate类,System.Delegate类则继承自System.Object。一个委托可以绑定若干相同签名的方法形成一个委托链,委托链是一个委托实例的集合,它允许我们调用这个集合中的委托实例所代表的所有方法(对于有返回值的方法,委托链的返回值为链表中最后一个方法的返回值),在下面的例子我们定义的委托方法都没有返回值。我们可以用 GetInvocationList()方法获取委托链。
class Program
{
static void Main(string[] args)
{
//Action 表示没有返回值的一类方法
Action<int, int> actionA = (x, y) =>
{
Console.WriteLine("x是{0},y是{1},他们的平方和是{2}", x, y, x * x + y * y);
};
actionA += (x, y) =>
{
Console.WriteLine("x是{0},y是{1},他们的平方差是{2}", x, y, x * x - y * y);
};
actionA(10, 5);
foreach (var item in actionA.GetInvocationList())
Console.WriteLine(item.Method);
Console.ReadLine();
}
}
什么是事件
经常看到一种定义是:事件是一种特殊的委托,是对委托的封装。其实这种定义是很不严谨的。委托是一种数据类型,但是事件只是委托的实例,不能算是一种数据类型,所以说事件是一种特殊的委托是不准确的。如果这样定义:事件是一种特殊的委托实例,是对委托的封装。那么在C#中事件是如何定义并被使用的呢?其实事件从定义到使用要经过四个阶段。










