C#委托
一 使用委托
//1.声明一个委托类型 internal delegate void Feedback(int value); class Program { //2. 定义一个符合委托类型的方法 private static void FeedbackToConsole(int x) { Console.WriteLine(x.ToString()); } static void Main(string[] args) { //3.构造委托实例 Feedback fb = new Feedback(FeedbackToConsole); //4. 调用委托 fb(2); } }
二 委托做了什么
当我们声明一个委托类型的时候,编译器实际帮我们定义了一个继承自MulticastDelegate的类
internal class Feedback : MulticastDelegate { //构造器 public Feedback(Object o, IntPtr m); //这个方法和源代码指定的原型一样 public virtual void Invoke(int value); //以下方法实现了对回调方法的异步回调 public virtual IAsyncResult BeginInvoke(int value, AsyncCallback callback, Object o); public virtual void EndInvoke(IAsyncResult result); }
MulticastDelegate的三个重要非公共字段
-
- _target System.Object 当委托对象包装一个静态方法时,这个字段为null;实例方法时,这个值为回调方法要操作的对象。
- _methodPtr System.IntPtr 一个内部整数值,CLR用它标识要回调的方法
- _invocationList System.Object 构造一个委托链时,引用一个委托数组
三 委托链
四 泛型委托
一般情况下我们不需要自己定义委托类型,.NET Framework为我们定义了两类泛型委托,分别是 Action和Func。每一类都有0-16个泛型参数的版本。Action无返回值,Func有返回值。
五 那些让人迷惑的简化语法
1. 不需要构造委托对象。
我们经常看到这样的写法:
button1.Click += button1_Click; (button1_Click是方法名)
这是一种简化的写法,完整的写法:
button1.Click += new EventHandler(button1_Click);
在前面使用委托的第三步我们也可以这样写:Feedback fb = FeedbackToConsole;
2. 不需要定义回调方法。
很多时候我们创建的回调方法只会使用一次,C#允许我们以内联的方式写回调方法的代码。例如我们可以把使用委托中的第二步省略,第三步改写为:
Feedback fb = x => Console.WriteLine(x.ToString());
“=>”是Lambda表达式操作符,“=”号右边的部分是一个Lambda表达式。编译器看到Lambda表达式后会自动定义一个新的私有方法,这个新方法称为匿名函数,因为方法的名称是编译器自动创建的。
3. 局部变量不需要手动包装到类中即可传给回调方

浙公网安备 33010602011771号