C# 反射 - 转换私有对象字段

发布于 2024-08-26 19:30:43 字数 1338 浏览 8 评论 0原文

我有以下类:

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 对象的“State”设置为 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)。是否可以检索 ErrorMessages ?

编辑:我应该澄清事件处理程序位于不同的程序集中,并且我无法引用第一个程序集(包含 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;

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

漆黑的白昼 2024-09-02 19:30:43

您不需要对此进行反射,只需将 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....
 } 

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

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

一曲琵琶半遮面シ 2024-09-02 19:30:43

一个例子....

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

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);
久光 2024-09-02 19:30:43

您需要传递 MyClass 的实例:

errorMessagesInfo.GetValue(someInstanceOfMyClass, null);

如果发送者的类型为 MyClass,则意味着:

errorMessagesInfo.GetValue(sender, null);

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);
格子衫的從容 2024-09-02 19:30:43

解决方案:

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;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文