C# ci consente to create custom event accessors.Il campo di supporto di un evento generato dal compilatore garantisce sempre lo stesso nome dell'evento?
Action _custom;
public event Action Custom
{
add { _custom = (Action)Delegate.Combine(_custom, value); }
remove { _custom = (Action)Delegate.Remove(_custom, value); }
}
Se non vengono specificate, the compiler creates them for you. Linguaggio C# spec:
Quando si compila un evento di campo simile, il compilatore crea automaticamente stoccaggio per tenere il delegato, e crea di accesso per l'evento che aggiungere o rimuovere i gestori di eventi al campo delegato.
Il codice sorgente decompilato utilizzando dotPeek per un semplice public event Action Public;
si presenta come segue:
private Action Public;
public event Action Public
{
add
{
Action action = this.Public;
Action comparand;
do
{
comparand = action;
action = Interlocked.CompareExchange<Action>(
ref this.Public, comparand + value, comparand);
}
while (action != comparand);
}
remove
{
Action action = this.Public;
Action comparand;
do
{
comparand = action;
action = Interlocked.CompareExchange<Action>(
ref this.Public, comparand - value, comparand);
}
while (action != comparand);
}
}
Degno di nota è che il campo e l'evento utilizzano lo stesso nome. Ciò ha portato some people a concludere che è possibile trovare informazioni sul campo di supporto durante la riflessione, cercando il campo nella classe con lo stesso nome dell'evento. Ho implementato in questo modo:
public static FieldInfo GetFieldInfo(this EventInfo eventInfo)
{
Contract.Requires(eventInfo != null);
return eventInfo.DeclaringType.GetField(
eventInfo.Name,
BindingFlags.DeclaredOnly | BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic);
}
questo funziona, ma solleva la questione: è il campo appoggio di un evento generato compilatore sempre garantito per utilizzare lo stesso nome come l'evento?
Non è possibile creare accessors di eventi personalizzati che accedono a un delegato con lo stesso nome utilizzando Visual Studio. Questo risulta nel messaggio: "Il membro con lo stesso nome è già dichiarato." Mi chiedo se sia possibile concludere che qualsiasi evento per il quale non è disponibile alcun backing delegato con lo stesso nome è un evento con accessor personalizzati.
_ "Posso chiederti perché vuoi sapere queste cose?" _ 1. Perché è divertente e istruttivo! :) 2. Stavo scrivendo un aspetto usando [PostSharp] (http://www.sharpcrafters.com/) che a un certo punto dovevo conoscere il delegato del backing field. Ho pensato che potrebbe essere un problema ed è stato in grado di utilizzare un altro approccio. –
3. Poiché non ho riscontrato problemi sollevati ad es. [questa risposta] (http://stackoverflow.com/questions/3783267/how-to-get-a-delegate-object-from-an-eventinfo/3783491#3783491) ho pensato che valesse la pena di chiederlo in modo specifico. Sto iniziando a vedere una correlazione tra le mie domande e il terzetto magico che risponde loro. Molte grazie! :) Noterò anche che dovrei davvero iniziare a leggere quella specifica C#. Roba interessante! –
E una divulgazione completa al 100%, sto scrivendo un aspetto che elimina la necessità per me di scrivere _ "delegate {}" _ durante la creazione di eventi, [quindi la mia domanda precedente] (http://stackoverflow.com/q/9823457/590.790). :) Ho appena ottenuto un calcio da questo tipo di cose. Anche se potrebbe essere eccessivo, è un ottimo modo per imparare. :) –