Почему я не могу добавить делегат в свой интерфейс?
Почему я не могу помещать делегат в интерфейс?
Ответ 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
В документации четко указано, что вы можете определить делегат в интерфейсе:
Интерфейс содержит только подписи методов, делегатов или события.
Однако в примечаниях на той же странице говорится, что интерфейс может содержать подписи методов, свойств, индексаторов и событий.
Если вы попытаетесь поместить делегата в интерфейс, компилятор говорит, что "интерфейсы не могут объявлять типы".
Стандарт 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();
}
}
}