469,646 Members | 1,152 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,646 developers. It's quick & easy.

GetFileld fails - ReflectionPermission problem?

dan
Hi all,
I have a reflection-problem I'm totally stuck with. Maybe someone has a
hint...
I want to get a fieldinformation of an event from the Control class, e.g.
"TextChanged".

FieldInfo fi = typeof(Control).GetField("TextChanged",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Public);

This should return the FieldInfo of the Control.TextChanged-event.But it
doesn't! It returns null.
If I do the same code on my self defined class, it works perfectly. The only
thing I can guess, is that
I should grant permission with ReflectionPermission. I have the default
settings for security and the
security tool tells me there is no security on the windows.forms-assembly.

Anybody can help me?
Thanks in advance

Dan

Full code below:
-------------------------

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Reflection;

namespace ReflectionTest
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Tester
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
//MyClass
EventInfo ei1 = typeof(MyClass).GetEvent("MyEvent");
FieldInfo fi1 = typeof(MyClass).GetField("MyEvent",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Public);

//Control
EventInfo ei2 = typeof(Control).GetEvent("TextChanged");
FieldInfo fi2 = typeof(Control).GetField("TextChanged",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Public);

//why is fi2 == null ?????
}

class MyClass
{
public event EventHandler MyEvent;
}
}
}

Nov 15 '05 #1
3 4162
dan <da*@dontsend.com> wrote:
I have a reflection-problem I'm totally stuck with. Maybe someone has a
hint...
I want to get a fieldinformation of an event from the Control class, e.g.
"TextChanged".

FieldInfo fi = typeof(Control).GetField("TextChanged",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Public);

This should return the FieldInfo of the Control.TextChanged-event.But it
doesn't! It returns null.


Events aren't necessarily stored as fields. In Control, for instance, I
believe that all the events are stored in the component's
EventHandlerList.

Think of it as being similar to properties - just because there's a
property named Foo doesn't mean there's necessarily a field backing it
called foo.

Indeed, it's not even necessary that your code will work on your own
class. The C# compiler is free to use whatever field name it wants. For
instance, the language specification has this example:

<quote>
Thus, an instance event declaration of the form:

class X {
public event D Ev;
}

could be compiled to something equivalent to:

class X {
private D __Ev; // field to hold the delegate
public event D Ev {
add {
lock(this) { __Ev = __Ev + value; }
}
remove {
lock(this) { __Ev = __Ev - value; }
}
}
}

Within the class X, references to Ev are compiled to reference the
hidden field __Ev instead. The name "__Ev" is arbitrary; the hidden
field could have any name or no name at all.
</quote>

It so happens that the MS C# compiler picks the same name for the field
as for the event, but that's not in the specification - and that's only
field-like events, let alone events which don't use a "field per
event" model at all.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #2
dan <da*@dontsend.com> wrote:
I have a reflection-problem I'm totally stuck with. Maybe someone has a
hint...


<snip>

In my previous post I told you why it didn't work. I neglected to give
you an alternative :)

I suggest you get the event itself using Type.GetEvent instead. You can
then add/remove handlers from it.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #3
dan
Hi Jon,
thanks a lot for this very fast and precise answer! You're completly right.
I checked it out with Anakrino.
That's the code it decompiles.

public void add_KeyPress(KeyPressEventHandler value)
{
this.Events.AddHandler(Control.EventKeyPress, value);
}

So Control adds its events effectively to the Events property of the
Component class.
I spent a few hours the find a solution. But I'm really happy to know why it
didn't work :-)

The purpose behind my question actually was to figure out, which handler are
attached at the event.
In a class, where the event is defined as a "real" event, I could do so by
writing the following code:

object val= fieldinfo.GetValue(anObject);
MulticastDelegate md = (MulticastDelegate)val;
Delegate[] list = md.GetInvocationList();

This would have been a general way to figure out which events are attached
to an event.
Obviously, this doesn't work on Control. Instead I could get the events
field, which is an EventHandlerList
and ask it for the contained handlers.

Anyway, it was a pleasure to get incredible fast such a competent answer!

Daniel Frey


"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP***********************@msnews.microsoft.co m...
dan <da*@dontsend.com> wrote:
I have a reflection-problem I'm totally stuck with. Maybe someone has a
hint...
I want to get a fieldinformation of an event from the Control class, e.g. "TextChanged".

FieldInfo fi = typeof(Control).GetField("TextChanged",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Public);

This should return the FieldInfo of the Control.TextChanged-event.But it
doesn't! It returns null.


Events aren't necessarily stored as fields. In Control, for instance, I
believe that all the events are stored in the component's
EventHandlerList.

Think of it as being similar to properties - just because there's a
property named Foo doesn't mean there's necessarily a field backing it
called foo.

Indeed, it's not even necessary that your code will work on your own
class. The C# compiler is free to use whatever field name it wants. For
instance, the language specification has this example:

<quote>
Thus, an instance event declaration of the form:

class X {
public event D Ev;
}

could be compiled to something equivalent to:

class X {
private D __Ev; // field to hold the delegate
public event D Ev {
add {
lock(this) { __Ev = __Ev + value; }
}
remove {
lock(this) { __Ev = __Ev - value; }
}
}
}

Within the class X, references to Ev are compiled to reference the
hidden field __Ev instead. The name "__Ev" is arbitrary; the hidden
field could have any name or no name at all.
</quote>

It so happens that the MS C# compiler picks the same name for the field
as for the event, but that's not in the specification - and that's only
field-like events, let alone events which don't use a "field per
event" model at all.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by MMJ | last post: by
2 posts views Thread by Budhi Saputra Prasetya | last post: by
reply views Thread by Budhi Saputra Prasetya | last post: by
3 posts views Thread by CMorgan | last post: by
18 posts views Thread by Eric | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.