反射によってフィールドを参照する方法
-
30-09-2019 - |
質問
タイトルをごめんなさい、それは明示的ではありません。
さらに私の先例の質問に, 、動的に取得したイベントオブジェクトのメソッドを(反射経由で)サブスクライブしたいと思います。問題のオブジェクトは、コントロールのフィールドです。
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は、タイプ「WindowsFormSApplication1.form1」で定義された型で定義されたunhandled message = field 'button1'は、「system.windows.forms.button」のタイプのターゲットオブジェクトのフィールドではありません。
解決
それはあなたがの新しいインスタンスを作成しようとしているからです 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);
}
所属していません StackOverflow