通过对类型和模板参数进行反射设置事件处理程序



我只想通过反射设置事件处理程序,我可以得到所有类型,但我无法实现。

public delegate void MyHandler<T>(IMyInterface<T> pParam);    
public interface IMyInterface<T> 
{
    MyHandler<T> EventFired { get; set; }
}
void myFunction()
{
    //admit vMyObject is IMyInterface<ClassA>
    var vMyObject = vObj as IMyInterface<ClassA>;
    //get the generic type => ClassA
    var vTypeGeneric = vTypeReturn.GenericTypeArguments.FirstOrDefault();
    //build the type handler for the event MyHandler<ClassA>
    Type vAsyncOP = typeof(MyHandler<>).MakeGenericType(vTypeGeneric);
    // here I don't know how to create the Event handler to set EventFired 
    // dynamically with the code inside 
    var vEventFired = vMyObject.GetType().GetProperty("EventFired");
    vEventFired.SetMethod etc...
}

我找到了一些使用lambda/expression的代码,但在这种情况下我不明白如何使用它。

完整示例:

public delegate void MyHandler<T>(IMyInterface<T> pParam);
public interface IMyInterface<T>
{
    MyHandler<T> EventFired { get; set; }
}
public class MyClass : IMyInterface<int>
{
    public MyHandler<int> EventFired { get; set;}
}
public void ConcreteHandler(IMyInterface<int> p)
{
    Console.WriteLine("I'm here");
}
void Main()
{
    var myValue = new MyClass();
    var deleg = Delegate.CreateDelegate(typeof(MyHandler<int>), this, "ConcreteHandler");
    myValue.GetType().GetProperty("EventFired").SetValue(myValue, deleg);
    // Test delegate invocation:
    myValue.EventFired.Invoke(new MyClass());
}

由于问题询问有关设置事件的问题,并且代码是指委托,这是使用反射设置事件的代码(通过扩展方法):

public delegate void MyHandler<T>(IMyInterface<T> pParam);
public interface IMyInterface<T>
{
    event MyHandler<T> EventFired;
}
public class ClassA : IMyInterface<int>
{
    public event MyHandler<int> EventFired;
    private int _Count = 0;
    public void Fire()
    {
        var handler = EventFired;
        if (handler != null) handler(this);
    }
    public override string ToString()
    {
        return "Call: " + (++_Count).ToString();
    }
}
public static class Extension
{
    public static void Add<T>(this IMyInterface<T> i, System.Reflection.MethodInfo method, object method_instance = null)
    {
        if (method.IsGenericMethodDefinition) method = method.MakeGenericMethod(typeof(T));
        Delegate d = Delegate.CreateDelegate(typeof(MyHandler<>).MakeGenericType(typeof(T)), method_instance, method);
        i.GetType().GetEvent("EventFired").GetAddMethod().Invoke(i, new object[] { d });
    }
}
public class Program
{
    public static void Print<T>(IMyInterface<T> val)
    {
        string output = val.ToString();
        Console.WriteLine(output);
        System.Diagnostics.Debug.WriteLine(output);
    }
    static void Main(string[] args)
    {
        ClassA ca = new ClassA();
        ca.EventFired += Print<int>;
        ca.Add(typeof(Program).GetMethod("Print", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public));
        ca.Fire();
    }
}

对不起标题,我的意思不是事件,而是代表属性。我找到了解决方案:

public void MyDelegate<T>(IMyInterface<T> pParam)
{
}
void myFunction()
{
    //admit vMyObject is IMyInterface<ClassA>
    var vMyObject = vObj as IMyInterface<ClassA>;
    //get the generic type => ClassA
    var vTypeGeneric = vTypeReturn.GenericTypeArguments.FirstOrDefault();
    //build the type handler for the event MyHandler<ClassA>
    Type vAsyncOP = typeof(MyHandler<>).MakeGenericType(vTypeGeneric);
    // SOLUTION here :
    // Create MyDelegate<vTypeGeneric>
    // Then instanciate it with CreateDelegate and typeof(IMyInterface<vTypeGeneric>)
    var vMyDelegate= this.GetType().GetMethod("MyDelegate");
    var vMyDelegateGeneric = vMyDelegate.MakeGenericMethod(vTypeGeneric);
    Type vTypeHandlerGeneric = typeof(IMyInterface<>).MakeGenericType(vTypeGeneric);
    // this => bind to method in the class
    var vMethodDelegate = vMyDelegateGeneric.CreateDelegate(vTypeHandlerGeneric, this);
    // Set delegate Property
    var vEventFired = vMyObject.GetType().GetProperty("EventFired");
    vEventFired.SetValue(value, vDelegate);
}

最新更新