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

为什么C#使用dynamic调用外部程序集方法会在运行时抛出异常?

问题根因

你遇到的异常本质是C# dynamic的运行时绑定逻辑依旧遵守访问权限控制规则,不会绕过类型可见性限制:

  • 你外部dll中定义的ProxyFactory是internal修饰的,仅在a.b.c程序集内部可见,你的业务代码所在的程序集没有访问该类型成员的权限
  • 动态绑定时,因为调用方无法识别ProxyFactory类型,会将其当做object类型处理,自然找不到Get方法
  • 调试时反射能看到Get方法是因为反射默认不校验访问修饰符限制,和dynamic的绑定逻辑不同
解决方案

不需要强制用反射Invoke的方式实现需求,可根据实际情况选择以下成本更低的方案:

  • 方案1(优先推荐,仅需修改外部dll少量代码):将FactoryCreator.CreateFactory的返回值类型从internal的ProxyFactory改为public的FactoryIfc接口:
namespace Ext
{
  public static class FactoryCreator
  {
    // 仅修改返回值类型为公开接口
    public static FactoryIfc CreateFactory()
    {
        return new ProxyFactory();
    }
  }
}

因为FactoryIfc是公开类型,dynamic绑定时可以正常识别到接口定义的Get方法,业务代码无需改动即可正常运行。

  • 方案2(无需修改外部dll,性能最优):如果你的业务项目已经引用了外部dll的公开元数据,直接将返回实例转换为FactoryIfc接口调用即可,不需要用dynamic:
var assembly = "a.b.c, Version=1.0.0.0, Culture=neutral, PublicKeyToken=<key>,processorArchitecture=MSIL";
var instName = "Ext.FactoryCreator";
Ext.FactoryIfc factory = (Ext.FactoryIfc)AppDomain.CurrentDomain.Load(assembly)
    .GetType(instName)
    .GetMethod("CreateFactory")
    .Invoke(null, new object[0]);
var proxy = factory.Get();
  • 方案3(无法修改外部dll代码时可选):给外部dll添加InternalsVisibleTo特性,授权你的业务程序集访问它的内部成员:
    在外部dll的AssemblyInfo.cs文件中添加如下代码:
[assembly: InternalsVisibleTo("你的业务程序集名称, PublicKey=<业务程序集强签名公钥(非强签名可省略>")]

配置后dynamic即可正常识别ProxyFactory的内部成员。

内容的提问来源于stack exchange,提问作者NirMH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:15:03