代表不仅仅是速记界面吗?

假设我们有:

interface Foo { bool Func(int x); } class Bar: Foo { bool Func(int x) { return (x>0); } } class Baz: Foo { bool Func(int x) { return (x<0); } } 

现在我们可以将Bar和Baz作为Foos折腾并调用他们的Func方法。

代表们对此进行了简化:

 delegate bool Foo(int x); bool Bar(int x) { return (x0); } 

现在我们可以像Foo代表一样折腾Bar和Baz。

除了获得更短的代码之外,代表们的真正好处是什么?

稍有不同,委托可以访问定义它们的类的成员变量。 在C#中(与Java不同),所有内部类都被认为是静态的。 因此,如果您使用接口来管理回调,例如按钮的ActionListener。 实现内部类需要传递(通过构造函数)对回调期间可能需要与之交互的包含类的部分的引用。 代表没有此限制因此减少了实现回调所需的代码量。

更短,更简洁的代码也是值得的好处。

从软件工程的角度来看,你是对的,委托很像函数接口,因为它们是函数接口的原型。

它们也可以以相同的方式使用:不是传递包含您需要的方法的整个类,而是只传递一个委托。 这样可以节省大量代码并创建更易读的代码。

此外,随着lambda表达式的出现,它们现在也可以在飞行中轻松定义,这是一个巨大的奖励。 虽然在C#中动态构建类是可能的,但它确实是一个巨大的痛苦。

比较两者是一个有趣的概念。 我以前没有考虑过用例和代码结构的观点有多大相似之处。

委托人与来自调用者的角度的单一方法的接口引用共享很多共同点。

在第一个示例中,Baz和Bar是类,可以inheritance和实例化。 在第二个例子中,Baz和Bar是方法。

您不能将接口引用仅应用于与接口契约匹配的任何类。 该类必须明确声明它支持该接口。 您可以将委托引用应用于与签名匹配的任何方法。

您不能在接口的合同中包含静态方法。 (尽管可以使用扩展方法来启动静态方法)。 您可以使用委托引用引用静态方法。

不,代表是方法指针。 然后,您可以确保与委托关联的方法的签名是正确的。

此外,您不需要知道类的结构。 这样,您可以使用已编写的方法传递到另一个类中的方法,并定义您希望发生的function。

使用Find方法查看List <>类 。 现在,您可以定义确定某些内容是否匹配的内容,而不需要类中包含的项目来实现IListFindable或类似内容。

您可以将委托作为参数传递给函数(在技术上,委托在编译时成为对象,但这不是重点)。 您可以将对象作为参数传递(显然),但是然后您将该类型的对象作为参数绑定到该函数。 使用委托,您可以传递任何函数以在具有相同签名的代码中执行,而不管它来自何处。

可以将委托视为方法的接口,该方法定义方法必须具有哪些参数和返回类型以适合委托

是的,委托可以被认为是一种方法的接口。

委托是类型化方法指针。 这为您提供了比接口更多的灵活性,因为您可以利用协方差和逆变,并且您可以修改对象状态(您必须通过基于接口的仿函数传递this指针)。

此外,代表们有很多很好的语法糖,可以让你轻松地将它们组合在一起。

接口和委托是两个完全不同的东西,虽然我理解以类似界面的术语描述代表以便于理解的诱惑……然而,不了解真相可能会导致混乱。

代表们(部分)受到了启发,因为C ++方法指针的黑色艺术不适合某些目的。 一个典型的例子是实现消息传递或事件处理机制。 委托允许您在不了解类的类型或接口的情况下定义方法签名 – 我可以定义“void eventHandler(Event * e)”委托并在任何实现它的类上调用它。

有关这个经典问题的一些见解,以及为什么代表们需要阅读本文 ,然后阅读 本文 。

在至少一个向Java添加闭包(即匿名委托)的提议中,它们等同于具有单个成员方法的接口。