[英]Set Event-Handler by reflection with Type and Template argument
I would like to set an event handler only by reflection, I can get all the types but I can't achieve it. 我只想通过反射来设置事件处理程序,我可以获取所有类型,但无法实现。
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...
}
I found some code with the usage of Lambda/Expression but I don't understand how to use it in this case. 我发现了一些使用Lambda / Expression的代码,但在这种情况下我不明白如何使用它。
Full sample: 完整样本:
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());
}
Since the question asks about setting an event and the code refers to delegate, here is the code for setting an event using reflection (via extension method): 由于该问题询问有关设置事件的问题,并且代码涉及委托,因此以下是使用反射(通过扩展方法)设置事件的代码:
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();
}
}
Sorry for the title, I meant not an event but a delegate property. 对不起标题,我的意思不是事件,而是委托属性。 I found the solution meanwhile :
我同时找到了解决方案:
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.