将方法转换为内部嵌套委托类型时CreateDelegate调用失败求助
解决内部嵌套委托绑定
Delegate.CreateDelegate的ArgumentException问题 嘿,这个问题我之前踩过类似的坑,内部嵌套委托用Delegate.CreateDelegate绑定的时候,经常会因为访问权限或者签名匹配的问题抛出这个异常,咱们一步步来拆解解决:
1. 先确认签名完全匹配
首先得排除最基础的签名问题:你的OnEnterMenuMode方法必须和内部委托的签名完全一致,包括:
- 返回值类型(比如委托是
void,方法也必须是void) - 参数的数量、类型、顺序,包括
ref/out修饰符 - 甚至参数的泛型类型也要完全匹配(比如不能用
EventArgs代替派生的MouseEventArgs,哪怕继承关系存在)
你可以先手动写个委托实例测试,如果手动绑定都报错,那肯定是签名问题:
// 假设内部嵌套委托是SomeInternalClass.InternalMenuHandler InternalMenuHandler testHandler = OnEnterMenuMode;
2. 处理内部委托的访问权限
如果签名没问题,那大概率是访问权限的问题——因为委托是internal且嵌套的,默认的Delegate.CreateDelegate重载可能没有足够权限访问这个类型。这时候可以用带反射参数的重载来解决:
步骤:
- 先用反射获取到委托的
Type对象(如果当前程序集能直接引用委托类型,也可以直接用typeof(...)) - 用
GetMethod获取你的OnEnterMenuMode方法,指定正确的BindingFlags(比如方法是私有实例方法,就用BindingFlags.Instance | BindingFlags.NonPublic) - 调用带
MethodInfo参数的Delegate.CreateDelegate重载
示例代码:
// 获取内部嵌套委托的Type Type delegateType = typeof(SomeInternalClass.InternalMenuHandler); // 获取目标方法的MethodInfo MethodInfo targetMethod = typeof(YourClass).GetMethod( "OnEnterMenuMode", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(object), typeof(EventArgs) }, null ); // 创建委托 Delegate handler = Delegate.CreateDelegate(delegateType, this, targetMethod, throwOnBindFailure: true);
如果委托和方法不在同一个程序集,还需要给委托所在的程序集添加友元程序集声明(在委托程序集的AssemblyInfo.cs里):
[assembly: InternalsVisibleTo("YourCallingAssemblyName")]
3. 解决安全性透明性问题
错误信息里提到的“安全性透明性”,通常是因为:
- 你的代码运行在部分信任环境中
- 委托所在的程序集标记了
[SecurityTransparent]属性,而方法所在的程序集有更高的安全权限
解决办法:
- 如果是自己的程序集,可以给委托所在的程序集添加
[SecuritySafeCritical]属性,允许跨程序集的委托绑定 - 或者在调用
Delegate.CreateDelegate时,使用BindingFlags.IgnoreSecurity(谨慎使用,会跳过安全检查)
4. 最稳妥的绕路:用Lambda包装方法
如果反射的权限问题实在搞不定,用Lambda表达式包装你的方法是最简单的解决方案——通过闭包调用方法,绕过直接绑定的权限检查:
// 如果能直接引用委托类型 SomeInternalClass.InternalMenuHandler handler = (sender, e) => OnEnterMenuMode(sender, e); // 如果只能通过反射获取委托类型 Type delegateType = typeof(SomeInternalClass.InternalMenuHandler); Delegate handler = Delegate.CreateDelegate( delegateType, this, (Action<object, EventArgs>)OnEnterMenuMode );
这种方式几乎能解决所有权限相关的绑定问题,而且代码更简洁易读。
内容的提问来源于stack exchange,提问作者trigger_segfault
相关产品推荐
相关产品推荐

