views:

335

answers:

4

I have the following classes:

public class MyEventArgs : EventArgs
{
    public object State;

    public MyEventArgs (object state)
    {
        this.State = state;
    }

}

public class MyClass
{
     // ...

     public List<string> ErrorMessages 
     {
          get
          {
               return errorMessages;
          }
      }
}

When I raise my event, I set 'State' of the MyEventArgs object to an object of type MyClass. I'm trying to retrieve ErrorMessages by reflection in my event handler:

 public static void OnEventEnded(object sender, EventArgs args)
 {
      Type type = args.GetType();
      FieldInfo stateInfo = type.GetField("State");
      PropertyInfo errorMessagesInfo = stateInfo.FieldType.GetProperty("ErrorMessages");

      object errorMessages = errorMessagesInfo.GetValue(null, null);

  }

But this returns errorMessagesInfo as null (even though stateInfo is not null). Is it possible to retrieve ErrorMessages ?

Edit: I should clarify that the event handler is in a different assembly, and I cannot reference the first assembly (that contains MyEventArgs and MyClass) for build issues.

Thank you

Edit: Solution

FieldInfo stateInfo = args.GetType().GetField("State");
Object myClassObj = stateInfo.GetValue(args);
PropertyInfo errorMessagesInfo = myClassObj.GetType().GetProperty("ErrorMessages");
object errorMessagesObj = errorMessagesInfo.GetValue(myClassObj, null);
IList errorMessages = errorMessagesObj as IList;
A: 

You need to pass the instance of MyClass:

errorMessagesInfo.GetValue(someInstanceOfMyClass, null);

If the sender is of type MyClass that would mean:

errorMessagesInfo.GetValue(sender, null);
Darin Dimitrov
Thanks, but I don't have an instance of MyClass. Also, sender is an object of a different class.
alhazen
+2  A: 

You don't need reflection for this, just cast EventArgs to MyEventArgs and then you can access the ErrorMessages property:

 public static void OnEventEnded(object sender, EventArgs args) 
 { 
     MyEventArgs myArgs = (MyEventArgs)args;
     MyClass detail = (MyClass)myArgs.State;

     // now you can access ErrorMessages easily...
     detail.ErrorMessages....
 } 

You should avoid using reflection for something where they types are fully known. Instead, you should use type casting to convert the reference to the types you expect. Reflection makes sense when the type information is dynamic, or not available at compile time in your code (which doesn't appear to be the case).

LBushkin
OnEventEnded() is in another assembly and I cannot simply reference the assembly containing MyEventArgs and MyClass. Thanks
alhazen
+1  A: 

An example....

PropertyInfo inf = ctl.GetType().GetProperty("Value");
errorMessagesInfo.GetValue(ClassInstance, null);




//And to set a value
    string value = reader[campos[i]].ToString();
    inf.SetValue(ctl, value, null);
MaK
A: 

Solution:

FieldInfo stateInfo = args.GetType().GetField("State");
Object myClassObj = stateInfo.GetValue(args);
PropertyInfo errorMessagesInfo = myClassObj.GetType().GetProperty("ErrorMessages");
object errorMessagesObj = errorMessagesInfo.GetValue(myClassObj, null);
IList errorMessages = errorMessagesObj as IList;
alhazen