Pro C# 2008 第11章 委托、事件和Lambda


Pro C# 2008 第11章 委托、事件和Lambda

委托定义:C#中的回调。安全,面向对象。包含:

  • 所调用的方法的名称;
  • 该方法的参数(可选);
  • 该方法的返回值(可选)。

委托声明

delegate声明的是System.MulticastDelegate类。

public delegate int BinaryOp(int x, int y);

// 静态方法
BinaryOp b = new BinaryOp(SimpleMath.Add);

// 实例方法
BinaryOp b = new BinaryOp(m.Add);

// 这样调用都可以
b(10, 10);
b.Invoke(10, 10);

支持多播

使用 += 和 -= 运算符添加、移除方法。

委托协变

指向方法的返回类可以有继承关系。

委托逆变

指向方法的参数可以有继承关系。

泛型委托

public delegate void MyGenericDelegate(T arg);

C#事件

  • 使用event关键字和+=、-=运算符简化事件注册和移除。

  • 泛型EventHandler委托

C#匿名方法

  • 可以带或不带参数
c1.AboutToBlow += delegate
{
    aboutToBlowCounter++;
    Console.WriteLine("Eek!  Going too fast!");
};

c1.AboutToBlow += delegate(object sender, CarEventArgs e)
{
    aboutToBlowCounter++;
    Console.WriteLine("Message from Car: {0}", e.msg);
};
  • 可访问“外部变量”

方法组转换

// 注册时间处理程序
m.ComputationFinished += ComputationFinishedHandler;
// 显示转换委托
SimpleMath.MathMessage mmDelegate = (SimpleMath.MathMessage)ComputationFinishedHandler;

C# 3.0 Lambda运算符

匿名方法的简单形式,简化委托的使用。

// 无参数类型,参数无括号,表达式无括号
List evenNumbers = list.FindAll(i => (i % 2) == 0);
// 有参数类型,参数有括号,表达式无括号
List evenNumbers = list.FindAll((int i) => (i % 2) == 0);
// 无参数类型,参数有括号,表达式无括号
List evenNumbers = list.FindAll((i) => (i % 2) == 0);
// 无参数类型,参数有括号,表达式有括号
List evenNumbers = list.FindAll((i) => ((i % 2) == 0));

// 多行表达式
List evenNumbers = list.FindAll((i) =>
{
    Console.WriteLine("value of i is currently: {0}", i);
    bool isEven = ((i % 2) == 0);
    return isEven;
});

// Traditional delegate syntax.
c1.OnAboutToBlow(new Car.AboutToBlow(CarAboutToBlow));
c1.OnExploded(new Car.Exploded(CarExploded));

// Use anonymous methods.
c1.OnAboutToBlow(delegate(string msg) { Console.WriteLine(msg); });
c1.OnExploded(delegate(string msg) { Console.WriteLine(msg); });

// Using lambda expression syntax.
c1.OnAboutToBlow(msg => { Console.WriteLine(msg); });
c1.OnExploded(msg => { Console.WriteLine(msg); });

// 不带类型
m.SetMathHandler((string msg, int result) => { Console.WriteLine("Message: {0}, Result: {1}", msg, result); });
// 带类型
m.SetMathHandler((msg, result) => { Console.WriteLine("Message: {0}, Result: {1}", msg, result); });
// 无参数
VerySimpleDelegate d = new VerySimpleDelegate(() => { return "Enjoy your string!"; });