Hi Wiktor,
Interesting example.
The behaviour you're observing must be due to the fact that the
Click event of the Button class isn't implemented as a delegate field.
Though events are usually implemented that way (as in your first
example) alternative ways are possible.
Paragraph 17.7.2 of the C# languague specification (the ECMA version)
talks about manually implementing event accessors:
"One situation for doing so involves the case in which the storage cost
of one field per event is not acceptable. In such cases, a class can include
event-accessor-declarations and use a private mechanism for storing the
list of event handlers."
- Magnus
"Wiktor Zychla" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Let's start with an example: if you have:
>
> class Test
> {
> public delegate int MyDelegate( int n );
> event MyDelegate MyEvent;
> }
>
> then you can get MyEvent using reflection:
>
> Test test = new Test(...);
> Type t = typeof( Test );
> t.InvokeMember( "MyEvent", BindingFlags.Instance | BindingFlags.GetField |
> BindingFlags.NonPublic, null, test, null );
>
> this works like a charm, you get reference to the delegate of type
> MyDelegate.
>
> Then comes the problem: why following does not work:
>
> class MyForm : Form
> {
> Button b;
> ...
> }
>
> Type t = typeof( Button );
> t.InvokeMember( "Click", BindingFlags.Instance | BindingFlags.GetField |
> BindingFlags.NonPublic, null, b, null );
>
> this example looks like a perfect copy of above one. Click event is
> declared as field in Control class and thus, according to my intuition,
> should be available via reflection. I would expect to get a delegate of
> type EventHandler. instead an exception of missing member is thrown.
>
> I just hope I miss something obvious. If not, I really would like to hear
> a technical explanation, can be complicated, I am not afraid [I know how
> delegates and events work at IL level].
>
> Thanks in advance,
> Wiktor Zychla
>
|