.net - 如何通过反射引用字段

标签 .net reflection c#-2.0 fieldinfo

对不起,标题不明确。

Further to my precedent question ,我想为动态检索的事件对象订阅一个方法(通过反射)。有问题的对象是 Control 的一个字段:

public void SubscribeEvents(Control control)
{
    Type controlType = control.GetType();
    FieldInfo[] fields = controlType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    MethodInfo method = typeof(Trace).GetMethod("WriteTrace");

    // "button1" hardcoded for the sample
    FieldInfo f = controlType.GetField("button1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    // "Click" hardcoded for the sample
    EventInfo eInfo = f.FieldType.GetEvent("Click");

    if (eInfo != null)
    {
        EventHandler dummyDelegate = (s, e) => WriteTrace(s, e, eInfo.Name);
        Delegate realDelegate = Delegate.CreateDelegate(eInfo.EventHandlerType, dummyDelegate.Target, dummyDelegate.Method);
        eInfo.AddEventHandler(?????, realDelegate); // How can I reference the variable button1 ???
    }
}

我不知道如何引用变量“button1”。我试过这样的事情:
public void SubscribeEvents(Control control)
{
    Type controlType = control.GetType();
    FieldInfo[] fields = controlType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    MethodInfo method = typeof(Trace).GetMethod("WriteTrace");

    // "button1" hardcoded for the sample
    FieldInfo f = controlType.GetField("button1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    // "Click" hardcoded for the sample
    EventInfo eInfo = f.FieldType.GetEvent("Click");

    Type t = f.FieldType;
    object o = Activator.CreateInstance(t);

    f.GetValue(o);

    if (eInfo != null)
    {
        EventHandler dummyDelegate = (s, e) => WriteTrace(s, e, eInfo.Name);
        Delegate realDelegate = Delegate.CreateDelegate(eInfo.EventHandlerType, dummyDelegate.Target, dummyDelegate.Method);
        eInfo.AddEventHandler(o, realDelegate); // Why can I refer to the variable button1 ???
    }
}

但我这里有一个异常(exception):
        f.GetValue(o);

System.ArgumentException 未处理
Message=在类型“WindowsFormsApplication1.Form1”上定义的字段“button1”不是类型为“System.Windows.Forms.Button”的目标对象上的字段。

最佳答案

那是因为您正在尝试创建 Button 的新实例。并试图获取其 button1 的值属性(property),这显然不存在。

替换这个:

Type t = f.FieldType;
object o = Activator.CreateInstance(t);

f.GetValue(o);

有了这个:
object o = f.GetValue(control);

您可以使用这样的方法来获取任何对象的字段值:
public static T GetFieldValue<T>(object obj, string fieldName)
{
    if (obj == null)
        throw new ArgumentNullException("obj");

    var field = obj.GetType().GetField(fieldName, BindingFlags.Public |
                                                  BindingFlags.NonPublic |
                                                  BindingFlags.Instance);

    if (field == null)
        throw new ArgumentException("fieldName", "No such field was found.");

    if (!typeof(T).IsAssignableFrom(field.FieldType))
        throw new InvalidOperationException("Field type and requested type are not compatible.");

    return (T)field.GetValue(obj);
}

关于.net - 如何通过反射引用字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4336042/

相关文章:

c# - 不支持 Last 和 LastOrDefault

c# - 如何使用反射分析 C# 中的特殊类型约束?

java - 在迭代 map 时使用反射

c# - 列表中的最大日期时间

c# - 如何使用 C# 从 .asc 文件中的特定位置读取数据

c# - 为什么 C#/CLR 不支持方法重写协方差/反方差?

c# - .Net 4 - 在程序集中包含自定义信息

c# - 集合迭代期间出现异常并从该集合中删除项目

C# 将位图加载到 PictureBox 中 - 速度慢并且会阻塞 UI ..还有其他选择吗?

c# - 如何在不使用反射的情况下检查 .NET 程序集