This post originated from an RSS feed registered with .NET Buzz
by Adrian Florea.
Original Post: Explicitly calling event accessors
Feed Title: Web Log di Adrian Florea
Feed URL: /error.aspx?aspxerrorpath=/adrian/Rss.aspx
Feed Description: "You know you've achieved perfection in design, not when you have nothing more to add, but when you have nothing more to take away." Antoine de Saint-Exupery
Si sa che i metodi corrispondenti agli event accessor devono seguire un pattern di denominazione (vedi CLS Rule 33 e ECMA-335, Partition I, 10.4). Per esempio, l'accessore add deve seguire il pattern:
void add_<EventName> (<DelegateType> handler)
Luca, in questo interessante post, è arrivato ad aver bisogno di richiamare questi event accessor. Provando col compilatore C#, si ottiene l'errore CS0571 ("cannot explicitly call operator or accessor"). Vediamo se, per il seguente snippet, il compilatore C# genera per i metodi add_FooFired e AddFooFired lo stesso codice IL:
Questo è il codice per il corpo del metodo add_FooFired:
.maxstack 8 nop ldarg.0 dup ldfld class FooFiredEvent Foo::mFooFired ldarg.1 call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) castclass FooFiredEvent stfld class FooFiredEvent Foo::mFooFired ret
e questo per il corpo del metodo AddFooFired:
.maxstack 8 nop ldarg.0 dup ldfld class FooFiredEvent Foo::mFooFired ldarg.1 ldftn instance void FooFiredEvent::Invoke() newobj instance void FooFiredEvent::.ctor(object, native int) call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) castclass FooFiredEvent stfld class FooFiredEvent Foo::mFooFired ret
Si nota il fatto che i due snippet IL non sono perfettamente identici (vedi le righe in rosso). Come fare allora per poter richiamare esplicitamente il metodo add_FooFired? Semplice: scriviamo la classe Foo in Visual J#! :-)
Rimanendo in J#, si può richiamare add_FooFired (e per questo abbiamo il metodo "wrapper" AddFooFired), a differenza di C#, dove si ottiene, come abbiamo visto, l'errore CS0571. Così, potete tranquillamente richiamare AddFooFired da qualsiasi linguaggio .NET.
Una domanda: in un commento al post precedente, un ragazzo rumeno mi chiedeva se avessi l'intenzione di scrivere i post in inglese. A voi darebbe fastidio? - l'idea è di non aprire un altro blog