سؤال

آسف على العنوان ، إنه ليس واضحًا.

أبعد من سؤالي السابقة, ، أريد الاشتراك طريقة في كائن حدث تم استرداده ديناميكيًا (عبر الانعكاس). الكائن المعني هو حقل عنصر تحكم:

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

هل كانت مفيدة؟

المحلول

ذلك لأنك تحاول إنشاء مثيل جديد 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);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top