C#委托

Posted .NET开发菜鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#委托相关的知识,希望对你有一定的参考价值。

1、什么是委托

从数据结构来讲,委托是和类一样是一种用户自定义类型

委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址。调用委托的时候,委托包含的所有方法将被执行。

2、委托的定义

委托是类型,就好像类是类型一样。与类一样,委托类型必须在被用来创建变量以及类型对象之前声明。

委托的声明原型是
delegate <函数返回类型> <委托名> (<函数参数>)

例子:public delegate void MyDelegate(int number);//定义了一个委托MyDelegate,它可以注册返回void类型且有一个int作为参数的函数

3、委托的实例化

3.1 使用new关键字

委托实例化的原型是
<委托类型> <实例化名>=new <委托类型>(<注册函数>)
例子:MyDelegate _MyDelegate=new MyDelegate(CheckMod);//用函数CheckMod实例化上面的MyDelegate 委托为_MyDelegate

3.2 使用匿名方法

<委托类型> <实例化名>=delegate(<函数参数>){函数体};

3.3 使用Lambda表达式

 1  class Program
 2     {
 3         //声明委托
 4         delegate int MyDelegate(int x, int y);
 5 
 6         static void Main(string[] args)
 7         {
 8             //实例化委托
 9             //1、使用new关键字
10             MyDelegate _myDelegate = new MyDelegate(GetSum);
11 
12             //2、使用匿名方法
13             MyDelegate myDelegate = delegate(int x, int y)
14             {
15                 return x + y;
16             };
17 
18             //3、使用Lambda表达式
19             MyDelegate myDelegateLambda = (int x, int y) => { return x + y; };
20         }
21 
22         static int GetSum(int x, int y)
23         {
24             return x + y;
25         }
26     }

4、泛型委托

委托也支持泛型的使用
泛型委托原型:
delegate <T1> <委托名><T1,T2,T3...> (T1 t1,T2 t2,T3 t3...)

例如:delegate T2 DelegateDemo<T1,T2>(T1 t);//定义有两个泛型(T1,T2)的委托,T2作为委托函数返回类型,T1作为委托函数参数类型

static boo Check(int i)
{
     if(i%2==0)

     {

          return true; 

    }

     return false;
}

static void Main(string[] args)
{
      DelegateDemo<int, bool> _delegate =Check;//将泛型委托委托<T1,T2>实例化为<int,bool>,即表示有一个int类型参数且返回类型是bool的函数.
      Console.WriteLine(_delegate(9));//false
}

5、C#内置泛型委托

C#共有3种内置泛型委托

 1 namespace DelegateDemo
 2 {
 3     class Program
 4     {
 5         //声明委托
 6         delegate int MyDelegate(int x, int y);
 7 
 8         static void Main(string[] args)
 9         {
10             //1、Action<T>只能委托必须是无返回值的方法
11             Action<string> _action = new Action<string>(SayHello);
12             _action("Hello World");
13 
14             //2、Fun<TResult>只是委托必须有返回值的方法
15             Func<int, bool> _func = new Func<int, bool>(Check);
16             _func(5);
17 
18             //3、Predicate:此委托返回一个bool值,该委托通常引用一个"判断条件函数"。
19             //需要指出的是,判断条件一般为“外部的硬性条件”,比如“大于50”,而不是由数据自身指定,如“查找数组中最大的元素就不适合”。
20             Predicate<int> _predicate = new Predicate<int>(Check);
21             //使用Lambda表达式
22             Predicate<int> predicate = p => p % 2 == 0;
23             _predicate(26);
24         }
25 
26         static void SayHello(string strMsg)
27         {
28             Console.WriteLine(strMsg);
29         }
30 
31         //返回值为bool值
32         static bool Check(int i)
33         {
34             if (i % 2 == 0)
35             {
36                 return true;
37             }
38             return false;
39         }       
40     }
41 }

6、多播委托

实例化委托时必须将一个匹配函数注册到委托上来实例化一个委托对象,但是一个实例化委托不仅可以注册一个函数还可以注册多个函数,注册多个函数后,在执行委托的时候会根据注册函数的注册先后顺序依次执行每一个注册函数。

函数注册委托的原型:
<委托类型> <实例化名>+=new <委托类型>(<注册函数>)
例如:MyDelegate _myDelegate+=new MyDelegate(CheckMod);//将函数CheckMod注册到委托实例_checkDelegate上
在.net 2.0开始可以直接将匹配的函数注册到实例化委托:
<委托类型> <实例化名>+=<注册函数>
例如:MyDelegate _myDelegate+=CheckMod;//将函数CheckMod注册到委托实例_myDelegate上

注意:委托必须先实例化以后,才能使用+=注册其他方法。如果对注册了函数的委托实例从新使用=号赋值,相当于是重新实例化了委托,之前在上面注册的函数和委托实例之间也不再产生任何关系

有+=注册函数到委托,也有-=解除注册

例如:MyDelegate _myDelegate-=CheckMod;

如果在委托注册了多个函数后,如果委托有返回值,那么调用委托时,返回的将是最后一个注册函数的返回值。

 1 namespace DelegateDemo
 2 {
 3     class Program
 4     {
 5         //声明委托
 6         delegate int MyDelegate(int x, int y);
 7 
 8         static void Main(string[] args)
 9         {
10             MyDelegate _myDelegate = new MyDelegate(fun1);
11             _myDelegate += fun2;
12             Console.WriteLine(_myDelegate(10,23));
13 
14             Console.ReadKey();//输出10,返回最后一个注册函数的返回值
15         }
16 
17         static int fun1(int x, int y)
18         {
19             return x + y;
20         }
21 
22         static int fun2(int x, int y)
23         {
24             return x;
25         }      
26     }
27 }

 

以上是关于C#委托的主要内容,如果未能解决你的问题,请参考以下文章

C#系列:其实委托很简单(下)

C#之委托

我想从 C++ 非托管代码调用 C# 委托。无参数委托工作正常,但有参数委托使我的程序崩溃

C#之委托

C#事件

C#进阶系列16 委托