我在一个程序集中有以下代码:
namespace MyLibrary
{
class InternalClass
{
public event EventHandler<MyArgs> MyEvent;
public void RaiseMyEvent()
{
MyEvent(this, new MyArgs());
}
}
class MyArgs : EventArgs
{
}
}
以及另一个程序集中的以下代码:
namespace MyApp
{
class Program
{
static void Main()
{
var assembly = Assembly.LoadFrom(@"C:\path\to\MyLibrary.dll");
var types = assembly.GetTypes();
var internalClassType = types.FirstOrDefault(t => t.FullName == "MyLibrary.InternalClass");
var eventInfo = internalClassType.GetEvent("MyEvent");
var internalClass = Activator.CreateInstance(internalClassType);
eventInfo.AddEventHandler(internalClass,
Delegate.CreateDelegate(eventInfo.EventHandlerType, typeof(Program), "MyHandler"));
internalClassType.GetMethod("RaiseMyEvent").Invoke(internalClass, new object[0]);
}
public static void MyHandler(object sender, EventArgs e)
{
}
}
}
但是,我在Delegate.CreateDelegate
处收到以下异常:无法绑定到目标方法,因为其签名或安全透明度与委托类型的不兼容。
第一个程序集中的类型是内部的,不能更改,也不能授予朋友程序集访问权限。
我尝试通过以下方式动态创建方法:
namespace MyApp
{
class Program
{
static void Main()
{
var assembly = Assembly.LoadFrom(@"C:\path\to\MyLibrary.dll");
var types = assembly.GetTypes();
var internalClassType = types.FirstOrDefault(t => t.FullName == "MyLibrary.InternalClass");
var myArgsType = types.FirstOrDefault(t => t.FullName == "MyLibrary.MyArgs");
var eventInfo = internalClassType.GetEvent("MyEvent");
var methodInfo = typeof(Program).GetMethod("MyHandler");
var method = new DynamicMethod("MyHandlerImpl", null, new[] { typeof(object), myArgsType });
var generator = method.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Call, methodInfo);
generator.Emit(OpCodes.Ret);
var internalClass = Activator.CreateInstance(internalClassType);
eventInfo.AddEventHandler(internalClass, method.CreateDelegate(eventInfo.EventHandlerType));
internalClassType.GetMethod("RaiseMyEvent").Invoke(internalClass, new object[0]);
}
public static void MyHandler(object sender, EventArgs e)
{
}
}
}
但是,我在MethodBase.Invoke
得到以下异常:尝试使用方法'DynamicClass.MyHandlerImpl(System.Object,MyLibrary.MyArgs)'来访问类型'MyLibrary.MyArgs'失败。
当我无法访问EventArgs类型时,有什么方法可以处理事件吗?
答案 0 :(得分:1)
实际上,我想通了。
我改变了
var method = new DynamicMethod("MyHandlerImpl", null, new[] { typeof(object), myArgsType });
到
var method = new DynamicMethod("MyHandlerImpl", null, new[] { typeof(object), typeof(EventArgs) });
并使Program
课程公开,一切正常。