委托是C # 最常用的功能之一。它允许你传递一个函数作为函数指针。它是一种相同的C函数指针。
简而言之,委托与C的函数指针相同。它指的是另一个功能。
如Microsoft官方文档所述:
委托是一种类型,表示对具有特定参数列表和返回类型的方法的引用。实例化委托时,可以将其实例与具有兼容签名和返回类型的任何方法相关联。您可以通过委托实例调用 (或调用) 该方法。
在深入了解有关代表的技术术语之前,让我们先创建一个代表。
// 声明一个委托
int公共委托AddDelegate (int num1, int num2); // 1静态void Main( string [] args){AddDelegate d1 = new AddDelegate (add); // 2int结果 = d1(7,2) // 3控制台。WriteLine (结果);控制台。ReadKey( true ); }public static int add( int a, int b) // 函数{控制台。“一个委托叫我” (WriteLine);int res;res = a b;返回res; }
让我们通过上面的代码来讨论。
- 就在注释 #1中的主函数之前,我们声明了一个名为AddDelegate。委托的签名非常重要,因为委托只能引用匹配相同签名的函数。
- 我们创建了返回类型设置为整数的委托,它需要两个输入整数参数。
- 在注释 #2中,我们正在实例化委托并传递add函数作为引用。
- 在注释 #3中调用委托。
在上面运行,你应该得到输出如下图所示:
您需要记住的一件重要事情是,委托的签名必须与委托所指向的函数的签名匹配。不仅签名,而且返回类型应该匹配。
现在,我希望您了解如何创建和使用委托。代理的一些功能如下:
- 委托类似于C函数指针:
- 但它是类型安全
- 可以封装对象实例
- 可以封装方法
- 委托允许方法作为参数传递。
- 可以将代表链接在一起。
- 委托可用于定义回调方法。例如,您可以在事件中使用它。
- 委托可以编译匿名方法和lambda表达式。
您可以将lambda表达式封装在委托中,如下一个代码清单所示:
AddDelegate d2 = (a, b) =>{控制台。"委托lambda表达式" (WriteLine);int res1 = a b 10;返回res1;}; int结果2 = d2(10,20);控制台。WriteLine(result2);
您将获得预期的输出,如下图所示:
您可以使用多播委托在委托中封装多个函数。您可以使用多播委托将多个对象分配给对象的一个实例。换句话说,同一个委托实例可以有多个订阅者,这在将多个订阅者分配给一个事件时非常有用。考虑下面的代码清单,以了解多播委托的示例。
类程序{公共委托void AddDelegate (int num1, int num2);静态void Main( string [] args){AddDelegate d1 = 添加;d1 = add100;d1 = (int a, int b) =>{int res = (a b) * 1000;控制台。写线 (res);};d1(10, 20);控制台。ReadKey( true ); }公共静态void添加 (int a, int b){ int res;res = a b;控制台。写线 (res); }公共静态void add100( int a, int b){int res;res = a b 100;控制台。写线 (res);}}}
我们创建了一个委托,然后添加了多个函数来封装在委托实例引用中。我们将函数add、add100和lambda表达式添加到同一个委托实例引用。
现在,当我们调用委托时,所有这三个引用都将被调用,您将获得预期的输出,如下图所示。您可以使用or-在多播委托中添加或删除对象引用。
代表有两个更重要的概念
- 协方差
- 逆变
从本文开始,我们一直在说委托可以引用具有相同返回类型和签名的方法,但是,variance简化了这一要求。协方差和逆变为将委托类型与方法签名匹配提供了灵活性。
协方差允许方法具有比委托中定义的返回类型更派生的返回类型。逆变允许其参数类型的派生程度低于委托类型的方法。
为了理解协方差,让我们创建两个类,如下一个代码清单所示:
公共类动物{受保护的智力年龄;受保护的无效显示 (智力年龄){这个 .age = 年龄;控制台。WriteLine( 这个年龄);}} 狗类公共: 动物{公共字符串颜色;公共无效displayColor(){显示 (99);控制台。WriteLine( 此 .color);}}}
狗类继承动物类。因此,使用协方差,具有动物类型的委托可以指狗类型。我们正在创建具有返回类型动物的委托,并在下面的代码列表中分配狗类型的引用。由于委托的协方差特征,这是可能的。
公共委托动物AnimalDelegate (); 静态void Main( string [] args){AnimalDelegate an = newDog;an();控制台。ReadKey( true ); } 静态狗newDog(){狗d = 新狗 ();d.颜色 = “白色”d.displayColor();返回d;}
像方差一样,逆变允许我们使用具有类型参数的方法,这些参数是委托签名参数类型的基类型。现在我希望你理解C # 中的代表,你可以在需要的时候在你的项目中使用这个函数。除了上面介绍的主题之外,您可能还需要检查通用委托。
如果您喜欢这篇文章,请随时在这里查看Infragistics Ultimate Product suite </p