【问题标题】:C# Reflection - Casting private Object fieldC# 反射 - 强制转换私有对象字段
【发布时间】:2011-02-02 16:39:37
【问题描述】:

我有以下课程:

public class MyEventArgs : EventArgs
{
    public object State;

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

}

public class MyClass
{
     // ...

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

当我引发我的事件时,我将 MyEventArgs 对象的“状态”设置为 MyClass 类型的对象。我正在尝试通过在我的事件处理程序中的反射来检索 ErrorMessages:

 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);

  }

但这会将 errorMessagesInfo 返回为 null(即使 stateInfo 不为 null)。是否可以检索错误消息?

编辑:我应该澄清事件处理程序位于不同的程序集中,并且我无法引用第一个程序集(包含 MyEventArgs 和 MyClass)来解决构建问题。

谢谢

编辑:解决方案

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;

【问题讨论】:

    标签: c# reflection object private casting


    【解决方案1】:

    您不需要对此进行反射,只需将EventArgs 转换为MyEventArgs,然后您就可以访问ErrorMessages 属性:

     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....
     } 
    

    您应该避免对类型完全已知的内容使用反射。相反,您应该使用类型转换将引用转换为您期望的类型。当类型信息是动态的,或者在您的代码中在编译时不可用时,反射才有意义(似乎并非如此)。

    【讨论】:

    • OnEventEnded() 在另一个程序集中,我不能简单地引用包含 MyEventArgs 和 MyClass 的程序集。谢谢
    【解决方案2】:

    一个例子....

    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);
    

    【讨论】:

      【解决方案3】:

      你需要传递MyClass的实例:

      errorMessagesInfo.GetValue(someInstanceOfMyClass, null);
      

      如果发件人是 MyClass 类型,则意味着:

      errorMessagesInfo.GetValue(sender, null);
      

      【讨论】:

      • 谢谢,但我没有 MyClass 的实例。此外,sender 是不同类的对象。
      【解决方案4】:

      解决方案:

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-02
        • 1970-01-01
        • 2020-05-01
        • 1970-01-01
        • 2011-10-06
        • 1970-01-01
        相关资源
        最近更新 更多