-
委托的声明和方法的声明类似,不同的是必须要用delegate关键字。
-
由于委托是一种类型,所以可以独立声明。
-
使用委托时要先进行实例化,和类一样。可以使用new关键字来产生委托的新实例。
-
我们可以将一个或者多个与委托签名匹配的方法与委托实例关联,在随后调用委托时,就会调用多有与该委托实例关联的方法。
-
与委托关联的可以是任何类或者结构中的方法,也可以是静态方法,只要是可以访问的方法都可以。
例如:下面我们定义一个DoSome委托:
public delegate void DoSome(string msg);
然后我们需要分析哪些方法可以与DoSome委托匹配。DoSome委托可以匹配的方法的返回 值只能是void类型(即不返回任何内容),而且接受一个string类型的参数。
例如:static void TestDo(string str){}
TestDo这个方法可以和DoSome委托相关联public void Test2(int n){}
上面Test2方法是不能匹配的,因为它的参数不是string类型
public float WorkAs(){}
上面这个WorkAs方法也是不能和DoSome委托进行匹配的,因为它没有参数,返回值类型也不匹配
public void ToDone(string str1,string str2){}
上面这个ToDone方法也不能和DoSome委托进行匹配,虽然它返回void,参数也是string类型,但是它有两个参数,而DoSome委托只有一个参数,所以也不匹配。
-
任何数据类型都会隐藏含有公共基类,因为任何类型都是从System.Object类中派生。但是委托类型隐含的公共基类是System.Delegate或者System.MulticastDelegate类,后者实现了委托的多路广播,即一个委托类型的实例可以和多个方法相关联。在实际使用中,.NET框架所支持的每种编程语言都会实现与委托类型相关的关键字。在C#语言中为delegate,编译器会自动完成从System.Delegate或者System.MulticastDelegate类的隐藏继承,我们不能自己编写代码来继承这些类型,只能在代码中使用delegate关键字来声明委托类型,剩下的工作将由编译器来完成。
-
在实例化委托时,可以将要关联的方法作为参数来进行传递,例如,使用上面举例中的DoSome委托来跟与之匹配的TestDo方法进行关联,就可以这样来实例化:
DoSome d = new DoSome(TestDo); //用DoSome委托关联TestDo方法
还可以使用更简洁的方法来实例化委托
DoSome d = TestDo; -
调用委托时,与调用普通方法相似,有参数就传递参数,有返回值就接收返回值,例如:
d(“abc”);
-
委托之间可以进行相加和相减运算,但并不是数学中的加减运算,委托的加运算是增加所关联的方法,减法则是从委托所关联的方法列表中移除指定的方法。
例如:
d += new DoSome(TestRun); -
下面我们完成一个完整的例子,认识一下委托的用法。首先,在VS开发环境中新建一个C#的控制台应用程序项目。
接着,在项目生成的Program类中定义三个静态方法,这三个方法必须签名相同
static void TestMethod1(string str)
{
Console.WriteLine(“这是方法一.参数:{0}”, str);
}static void TestMethod2(string str)
{
Console.WriteLine(“这是方法二.参数:{0}”, str);
}static void TestMethod3(string str)
{
Console.WriteLine(“这是方法三.参数:{0}”, str);
}
三个方法都是有且仅有一个string类型的参数且返回值都是void(这就是我理解的签名相同) -
随后我们定义委托类型
public delegate void MyDelegate(string s); -
紧接着,我们在Main方法中创建三个MyDelegate实例,分别与上面的三个方法关联,并逐个进行调用。
//定义三个委托变量 MyDelegate d1, d2, d3; //d1关联TestMethod1方法 d1 = TestMethod1; //d2关联TestMethod1方法 d2 = TestMethod2; //d3关联TestMethod1方法 d3 = TestMethod3; //分别调用三个委托实例 Console.WriteLine("分别调用三个委托实例,输出结果如下:"); d1("d1"); d2("d2"); d3("d3"); Console.ReadKey();
屏幕输出结果如图所示:
-
接下来,再创建一个MyDelegate委托实例d4,并且与三个方法关联,在调用d4时就能同时调用这三个方法。
//先与TestMethod1方法关联 MyDelegate d4 = TestMethod1; //随后再与TestMethod2和TestMethod3方法进行关联 d4 += TestMethod2; d4 += TestMethod3; //调用d4 Console.WriteLine("\n调用d4可同时调用三个方法,结果如下:"); d4("d4"); Console.ReadKey();
-
屏幕输出结果如下
//先与TestMethod1方法关联 MyDelegate d4 = TestMethod1; //随后再与TestMethod2和TestMethod3方法进行关联 d4 += TestMethod2; d4 += TestMethod3; //调用d4 Console.WriteLine("\n调用d4可同时调用三个方法,结果如下:"); d4("d4"); Console.ReadKey();
-
现在,把TestMethod2方法从d4关联的方法列表中移除,并且再次调用d4
//从d4中关联的方法列表中减去TestMethod2方法 d4 -= TestMethod2; //再次调用d4 Console.WriteLine("\n移除与TestMethod2方法关联后:"); d4("d4"); Console.ReadKey();
屏幕输出结果如下: