以下所写是个人对委托的理解,为了加深对委托的理解和记忆,特地写下来。
委托的介绍:
委托和事件是一对好搭档,事件在之后的文章中做介绍。C#中常使用委托做回调。
委托其实是一个类,在编译之后的编译文件中可以看到,委托的类型是class。
C#和CLR都允许引用类型的协变性和逆变性。
协变性:指方法的返回类型派生的一个类型。
逆变性:指方法的参数可以是委托的参数类型的基类。
注意:斜边性和逆变性只能作用于引用类型,不能作用于值类型和void。值类型和void之所以不支持协变性和逆变性是因为它们的存储结构是变化的,而引用类型的存储结构始终是一个指针。
1.声明委托
使用关键字:delegate,
如下所示:这里声明了一个没有返回值的委托。
public delegate void ConsloleWrite(string str);
2.使用委托
public class Program { static void Main(string[] args) { Console.Write("请输入:"); string str = Console.ReadLine(); TestDelegate td = new TestDelegate(); td.DelegatePrint(Convert.ToInt32(str), print); } public static void print<T>(T str) { Console.WriteLine(str); Console.ReadKey(); } } public class TestDelegate { public void DelegatePrint<T>(T str,ConsloleWrite<T> write) { write(str); } public delegate void ConsloleWrite<in T>(T obj); }
3.使用委托回调很多方法(委托链)
委托链是由委托对象构成的一个集合。
使用Delegate的Combine方法来构建委托链,委托链其实也是一个委托。
委托链有两种写法,分别使用Combine、Remove方法,和+=、-=符号。+=和-=符号是为了简化委托链的使用,其实内部还是调用了Combine和Remove方法。
废话不多说,直接贴上代码……
public class Program { static void Main(string[] args) { Console.Write("请输入:"); string str = Console.ReadLine(); ConsoleWrite cw = null; //委托链的写法1 cw = (ConsoleWrite)Delegate.Combine(new ConsoleWrite(print), cw); cw = (ConsoleWrite)Delegate.Combine(new ConsoleWrite(print2), cw); cw = (ConsoleWrite)Delegate.Remove(cw, new ConsoleWrite(print2)); //委托链写法2 //cw += new ConsoleWrite(print); //cw += new ConsoleWrite(print2); ////移除委托链中的委托对象 //cw -= new ConsoleWrite(print2); TestDelegate td = new TestDelegate(); td.DelegatePrint(str, cw); Console.ReadKey(); } public static void print(string str) { Console.WriteLine("print:"+str); } public static void print2(string str) { Console.WriteLine("print2:" + str); } } public class TestDelegate { public void DelegatePrint(string str, ConsoleWrite write) { if (write != null) { write(str); } } } public delegate void ConsoleWrite(string obj);
最后在说一句,委托其实就是类,只要能声明类的地方就能声明委托。