簡體   English   中英

為什么我不能在接口中放置一個委托?

[英]Why can't I put a delegate in an interface?

為什么我不能向我的界面添加委托?

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

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

代表只是另一種類型,因此將其放在界面中不會獲得任何收益。

您不需要創建自己的代表。 大多數時候,您應該只使用 EventHandler、Func、Predicate 或 Action。

請問你的代表長什么樣?

Delegate是一種不能在接口中聲明的類型 您可能想要使用事件(如果適用)或在接口之外但在同一命名空間中聲明委托。

此鏈接可能會有所幫助-何時使用委托而不是接口

這是一個委托類型聲明......

public delegate returntype MyDelegateType (params)

this 不能在接口中聲明,因為它是類型聲明

但是使用上面的類型聲明,您可以使用委托實例

MyDelegateType MyDelegateInstance ( get; set;)

所以委托實例可以,但委托類型聲明不是(在接口中)

文檔清楚地表明您可以在接口中定義委托:

接口僅包含方法、委托或事件的簽名。

MSDN:接口(C# 參考)

但是,在同一頁的注釋中,它說接口可以包含方法、屬性、索引器和事件的簽名。

如果您嘗試將委托放在接口中,編譯器會說“接口不能聲明類型”。

Ecma-334 標准(8.9 接口)同意該頁面和編譯器上的注釋。

正如其他人所提到的,您只能在接口之外定義委托。

使用委托幾乎沒有錯。 我個人認為Func<int, double>不如使用委托:

  1. 您不能命名 arguments,因此參數含義可能不明確
  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 ,我不喜歡)。 如果您有很多 arguments 那么這可能會變得非常乏味(同樣,您可能總是很懶惰並使用var )。

     Func<int, double, string, object, short, string, object> 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();
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM