You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将方法转换为内部嵌套委托类型时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:30:20