为什么我不能在一个接口中放置一个委托?

为什么我不能在我的界面中添加委托?

您可以使用以下任何一种:

public delegate double CustomerDelegate(int test); public interface ITest { EventHandler MyHandler{get;set;} CustomerDelegate HandlerWithCustomDelegate { get; set; } event EventHandler MyEvent; } 

委托只是另一种类型,所以你不能通过将它放在界面中来获得任何东西。

您不需要创建自己的代理。 大多数情况下,您应该只使用EventHandler,Func,Predicate或Action。

请问您的代表是什么样的?

Delegate是一种无法在接口中声明的类型 。 您可能希望使用事件(如果适用)或在接口外部但在同一名称空间中声明委托。

此链接可能有所帮助 – 何时使用代理而不是接口

这是一个代表TYPE decalaration …

 public delegate returntype MyDelegateType (params) 

这不能在接口中声明,因为它是一个类型声明

但是使用上面的类型声明,您可以使用委托实例

 MyDelegateType MyDelegateInstance ( get; set;) 

所以委托实例是可以的但委托类型声明不是(在接口中)

文档清楚地说明您可以在界面中定义委托:

接口仅包含方法,委托或事件的签名。

MSDN:接口(C#参考)

但是,在同一页面上的备注中,它表示接口可以包含方法,属性,索引器和事件的签名。

如果您尝试将委托放在接口中,编译器会说“接口不能声明类型”。

Ecma-334标准(8.9接口)同意该页面和编译器的注释。

正如其他人所提到的,您只能在界面之外定义委托。

使用代表几乎没有错。 我个人认为Func不如使用委托:

  1. 您不能命名参数,因此参数含义可能不明确
  2. 事件不是线程安全的老消息,因此以下代码并不理想:

     if (MyFuncEvent != null) { MyFuncEvent(42, 42.42); } 

    请参阅: http : //kristofverbiest.blogspot.com/2006/08/better-way-to-raise-events.html

    更安全的代码是:

     MyFuncEventHandler handler = MyFuncEvent; if (handler != null) { handler(42, 42.42); } 
  3. 如果要将事件保存到变量中,则必须复制事件的签名(或者您可以使用我不喜欢的var )。 如果你有很多参数,那么这可能会非常繁琐(再次,你可能总是懒惰并使用var )。

     Func handler = MyFuncEvent; if (handler != null) { handler(42, 42.42, ...); } 

每次要将其分配给变量类型时,代理都可以使您不必复制方法/事件的签名。

接口方法可以接受委托作为参数,没有问题。 (也许我没有看到问题?)但是如果打算在界面中指定出站呼叫,请使用事件。

有很多细节,只是展示一些代码而不是试图用散文来描述它们要容易得多。 (对不起,即使代码示例有点臃肿……)

 namespace DelegatesAndEvents { public class MyEventArgs : EventArgs { public string Message { get; set; } public MyEventArgs(string message) { Message = message; } } delegate void TwoWayCallback(string message); delegate void TwoWayEventHandler(object sender, MyEventArgs eventArgs); interface ITwoWay { void CallThis(TwoWayCallback callback); void Trigger(string message); event TwoWayEventHandler TwoWayEvent; } class Talkative : ITwoWay { public void CallThis(TwoWayCallback callback) { callback("Delegate invoked."); } public void Trigger(string message) { TwoWayEvent.Invoke(this, new MyEventArgs(message)); } public event TwoWayEventHandler TwoWayEvent; } class Program { public static void MyCallback(string message) { Console.WriteLine(message); } public static void OnMyEvent(object sender, MyEventArgs eventArgs) { Console.WriteLine(eventArgs.Message); } static void Main(string[] args) { Talkative talkative = new Talkative(); talkative.CallThis(MyCallback); talkative.TwoWayEvent += new TwoWayEventHandler(OnMyEvent); talkative.Trigger("Event fired with this message."); Console.ReadKey(); } } }