Web Log di Adrian Florea

"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
posts - 440, comments - 2715, trackbacks - 3944

My Links

Archives

Post Categories

Image Galleries

.RO Blogs

.RO People

.RO Sites

Blogs

Furls

Links

vinCitori

Divertimento con il Reflector e un firing method

Se il seguente snippet:

delegate void FooFiredEvent();
 
class Foo
{
      public event FooFiredEvent FooFired;
     
      public void RaiseFooFired()
      {
            if (FooFired != null)
            {
                  FooFired();
            }
      }
}

lo compiliamo:

csc foo.cs

poi lo disassembliamo :

ildasm foo.exe /out=bar.il

e nel file disassemblato, bar.il, inseriamo la riga in rosso:

.event FooFiredEvent FooFired
{
      .addon instance void Foo::add_FooFired(class FooFiredEvent)
      .removeon instance void Foo::remove_FooFired(class FooFiredEvent)
      .fire instance void Foo::RaiseFooFired()
}

dopodiché lo riassembliamo:

ilasm /exe bar.il

e apriamo il file bar.exe col Reflector impostato per C#, avremo una sorpresa: nel codice disassemblato dell'evento FooFired, è apparsa una sezione, raise, che non c'è ancora nel linguaggio C# :-)

public event FooFiredEvent FooFired
{
      [MethodImpl(MethodImplOptions.Synchronized)] add
      {
            this.FooFired = (FooFiredEvent) Delegate.Combine(this.FooFired, value);
      }
      [MethodImpl(MethodImplOptions.Synchronized)] remove
      {
            this.FooFired = (FooFiredEvent) Delegate.Remove(this.FooFired, value);
      }
      raise
      {
            if (this.FooFired != null)
            {
                  this.FooFired();
            }
      }

}

Vediamo cosa dice Serge Lidin di questi firing methods nel suo libro (sottolineatura mia):

"An event can have at most one firing method. The firing method usually boils down to an invocation of the delegate implementing the event. The Visual C# .NET and Visual Basic .NET compilers, for example, never bother to define a firing method for an event—that is, the method invoking the delegate is there, but it is never associated with the event as a firing method. Such an approach contains a certain logic: the firing method is a purely internal affair of the event publisher and need not be exposed to the event subscribers. And because the compilers, as a rule, use the event metadata to facilitate subscription and unsubscription, associating a firing method with an event is not necessary. If an event does have an associated firing method, however, this method must return void".

Se si imposta il Reflector per altri linguaggi (Visual Basic, Delphi) questa "invenzione" non appare più.

(Aggiornamento 24/05/05):

All'interno del framework .NET 2.0.50215 ho trovato via reflection 3 eventi che hanno associato un firing method. La sorpresa delle sorprese è che tutti questi si trovano nell'assembly Microsoft.VisualBasic.dll :-)

Mi chiedo con quale linguaggio/compilatore sia scritto questo assembly (vuol dire che quel linguaggio/compilatore permette di associare firing methods agli eventi!).

Print | posted on lunedì 23 maggio 2005 22:47 | Filed Under [ Carillon .NET ]

Powered by:
Powered By Subtext Powered By ASP.NET