Подтвердить что ты не робот

Почему я не могу помещать делегат в интерфейс?

Почему я не могу добавить делегат в свой интерфейс?

4b9b3361

Ответ 1

Вы можете использовать любой из них:

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

Ответ 2

Делегат - это еще один тип, поэтому вы ничего не получаете, помещая его в интерфейс.

Вам не нужно создавать собственные делегаты. Большую часть времени вы должны просто использовать EventHandler, Func, Predicate или Action.

Могу ли я спросить, как выглядит ваш делегат?

Ответ 3

A Делегат - это тип, который не может быть объявлен в интерфейсе. Возможно, вы захотите либо использовать событие (если необходимо), либо объявить делегат вне интерфейса, но в том же пространстве имен.

Эта ссылка может помочь Когда использовать делегаты вместо интерфейсов

Ответ 4

это деляризация делегата TYPE...

public delegate returntype MyDelegateType (params)

этот cant должен быть объявлен в интерфейсе, так как это объявление типа

однако используя объявление типа выше, вы можете использовать экземпляр делегата

MyDelegateType MyDelegateInstance ( get; set;)

поэтому экземпляры делегирования в порядке, но объявления типа делегата отсутствуют (в интерфейсе)

Ответ 5

В документации четко указано, что вы можете определить делегат в интерфейсе:

Интерфейс содержит только подписи методов, делегатов или события.

MSDN: интерфейс (ссылка С#)

Однако в примечаниях на той же странице говорится, что интерфейс может содержать подписи методов, свойств, индексаторов и событий.

Если вы попытаетесь поместить делегата в интерфейс, компилятор говорит, что "интерфейсы не могут объявлять типы".

Стандарт Ecma-334 (8.9 Интерфейсы) согласуется с замечаниями на этой странице и компилятором.

Ответ 6

Как уже упоминалось, вы можете определять делегаты вне интерфейса.

Нет ничего плохого в работе с делегатами. Лично я считаю, что Func<int, double> менее желателен, чем использование делегатов:

  • Вы не можете назвать аргументы, поэтому значение аргумента может быть неоднозначным
  • Старые новости о том, что события не являются потокобезопасными, поэтому следующий код не идеален:

    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);
    }
    
  • Вам нужно дублировать подпись события, если вы хотите сохранить его в переменной (или вы можете использовать var, что мне не нравится). Если у вас много аргументов, это может стать очень утомительным (опять же, вы всегда можете быть ленивым и использовать var).

    Func<int, double, string, object, short, string, object> handler = MyFuncEvent;
    if (handler != null)
    {
        handler(42, 42.42, ...);
    }
    

Делегаты избавляют вас от необходимости дублировать подпись метода/события каждый раз, когда вы хотите присвоить его типу переменной.

Ответ 7

Метод интерфейса может принимать делегат в качестве параметра, без проблем. (Может быть, я не вижу проблемы?) Но если намерение заключается в определении исходящего вызова в интерфейсе, используйте событие.

Есть так много мелких деталей, гораздо проще просто показать код, а не пытаться описать все это в прозе. (Извините, даже пример кода немного раздутый...)

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();
        }
    }
}