2010-12-02 2 views
2

Извините за заголовок, это не явное.Ссылка на поле путем отражения

Further to my precedent question, Я хочу подписать метод для объекта события, полученного динамически (через отражение). Объектом является поле элемента управления:

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

Но у меня есть исключение здесь:

 f.GetValue(o); 

System.ArgumentException было необработанное сообщение = Поле 'Button1' определяется по типу 'WindowsFormsApplication1.Form1' является не поле на целевом объекте, которое имеет тип «System.Windows.Forms.Button».

ответ

5

Это потому, что вы пытаетесь создать новый экземпляр Button и пытаясь получить значение своего button1 свойства, которого, очевидно, не существует.

Заменить это:

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); 
} 
+0

У меня есть проблема: он отлично работает с button1 (и другими кнопками), но когда это настраиваемое поле, он возвращает null: объект o = f. ПолучитьЗначение (контроль); // если f является полевой информацией из поля типа MyClass, o = null Принимая во внимание, что f имеет хорошие значения – Florian 2010-12-02 15:51:08

 Смежные вопросы

  • Нет связанных вопросов^_^