我想只通过反射设置一个事件处理程序,我可以获得所有类型,但我无法实现它。
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的代码,但在这种情况下我不明白如何使用它。
答案 0 :(得分:0)
完整样本:
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());
}
答案 1 :(得分:0)
由于问题是关于设置事件并且代码引用委托,因此这里是使用反射设置事件的代码(通过扩展方法):
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();
}
}
答案 2 :(得分:0)
对不起标题,我的意思不是活动,而是委托财产。 我同时找到了解决方案:
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);
}