Perché non posso aggiungere un delegato alla mia interfaccia?Perché non posso inserire un delegato in un'interfaccia?
risposta
A Delegate è un type che non può essere dichiarato in un'interfaccia. Potresti voler utilizzare un evento (se appropriato) o dichiarare un delegato all'esterno dell'interfaccia ma nello stesso spazio dei nomi.
Questo collegamento può Aiuto- When to Use Delegates Instead of Interfaces
un delegato è solo un altro tipo, in modo da non guadagna nulla mettendolo all'interno dell'interfaccia.
Non è necessario creare i propri delegati. La maggior parte delle volte dovresti semplicemente usare EventHandler, Func, Predicate o Action.
Posso chiedere come si presenta il vostro delegato?
+1 non vedo perché qualcuno imposta un voto negativo ... – eglasius
Questa risposta in realtà ha anche risolto il mio problema che non ho mai trovato un modo piacevole per usare i delegati nelle situazioni in cui volevo usarli. Cioè non usare 'm :). –
È possibile utilizzare uno di questi:
public delegate double CustomerDelegate(int test);
public interface ITest
{
EventHandler<EventArgs> MyHandler{get;set;}
CustomerDelegate HandlerWithCustomDelegate { get; set; }
event EventHandler<EventArgs> MyEvent;
}
Perché creare CustomerDelegate quando è possibile utilizzare Func
Lo so, stavo solo illustrando che puoi usare praticamente tutto :) – eglasius
Diventa difficile capire parametri come Func
La documentazione dice chiaramente che è possibile definire un delegato in un'interfaccia:
Un'interfaccia contiene solo i firme di metodi, delegati o eventi.
MSDN: interface (C# Reference)
Tuttavia, nelle osservazioni sulla stessa pagina si dice che l'interfaccia può contenere firme di metodi, proprietà, indicizzatori ed eventi.
Se si tenta di inserire un delegato in un'interfaccia, il compilatore dice che "le interfacce non possono dichiarare tipi".
Lo standard Ecma-334 (8.9 Interfacce) concorda con le osservazioni su quella pagina e sul compilatore.
Sembra un errore in MSDN. Dovrebbero essere "le firme di metodi, proprietà o eventi", non dovrebbe? – configurator
questo è un decalaration delegato TIPO ...
public delegate returntype MyDelegateType (params)
questo cant essere dichiarata in un'interfaccia in quanto è una dichiarazione di tipo
comunque utilizzando la dichiarazione del tipo di cui sopra è possibile utilizzare un'istanza delegato
MyDelegateType MyDelegateInstance (get; set;)
modo delegare casi sono OK, ma le dichiarazioni di tipo delegato non sono (in un'interfaccia)
La migliore risposta finora. Al punto. Amo molto quando la gente va al punto invece di scrivere discorsi. – DavidGuaita
Come altri hanno già menzionato, è possibile definire solo i delegati all'esterno dell'interfaccia.
C'è poco o nulla di sbagliato usando i delegati. Personalmente penso che Func<int, double>
è meno desiderabile che utilizzano delegati:
- Non è possibile assegnare un nome gli argomenti, in modo che il significato argomento può essere ambiguo
E 'una notizia vecchia che gli eventi non sono thread-safe, pertanto la seguente il codice non è l'ideale:
if (MyFuncEvent != null) { MyFuncEvent(42, 42.42); }
See: http://kristofverbiest.blogspot.com/2006/08/better-way-to-raise-events.html
Il codice più sicuro è:
MyFuncEventHandler handler = MyFuncEvent; if (handler != null) { handler(42, 42.42); }
si deve duplicare la firma della manifestazione se si vuole salvarlo in una variabile (o si potrebbe utilizzare
var
, che non mi piace). Se hai molti argomenti, questo potrebbe diventare molto noioso (di nuovo, potresti sempre essere pigro e usarevar
).Func<int, double, string, object, short, string, object> handler = MyFuncEvent; if (handler != null) { handler(42, 42.42, ...); }
delegati si salva dal dover duplicare la firma del metodo/evento ogni volta che si desidera assegnare a un tipo di variabile.
Tuttavia, si noti che _can_ name gli argomenti nel sito di chiamata di una funzione lambda (ma solo se ce ne sono più di due): Azione
È bello sapere! – swooby
Un metodo di interfaccia può accettare un delegato come parametro, nessun problema. (Forse non vedo il problema?) Ma se l'intenzione è di specificare una chiamata in uscita nell'interfaccia, utilizzare un evento.
Ci sono così tanti piccoli dettagli, è molto più semplice mostrare semplicemente del codice invece di provare a descriverlo tutto in prosa. (Scusate, anche il codice di esempio è un po 'gonfio ...)
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();
}
}
}
È possibile: vedere di seguito: http://stackoverflow.com/a/612971/16454 – devlord