.NET Framework匿名对象作为dynamic参数传递报错问题
关于匿名对象传递给dynamic方法触发TypeAccessException的问题解答
这是个很典型的匿名类型与DLR(动态语言运行时)交互的权限问题,我来给你拆解清楚:
一、错误出现的原因
匿名类型在.NET Framework中默认是**internal(内部访问级别)**的——也就是说,只有定义它的程序集能直接访问它的成员。当你把匿名对象传给接收dynamic参数的方法时,DLR会在后台动态生成一个调用站点(CallSite),这个生成的动态类属于一个临时的动态程序集,它尝试访问你的internal匿名类型时,就触发了TypeAccessException——因为跨程序集访问internal类型是CLR严格禁止的。
而.NET Core/.NET 5+对匿名类型的访问规则和DLR的处理逻辑做了底层调整,让动态调用可以合法访问匿名类型成员,所以不会出现这个错误。
针对你提到的几个场景:
- VS2017:默认搭配的是C# 7.x系列编译器,当时的编译器和DLR交互逻辑没有针对这个场景做优化,所以会触发异常。
- .NET Framework 4.8:虽然是.NET Framework的最终版本,但它的DLR组件没有修复跨程序集访问internal匿名类型的问题,因此依然会报错。
- dotnetfiddle(.NET Framework环境):使用的是标准的.NET Framework运行时和对应版本的编译器,自然也会遇到同样的权限问题。
二、修复所需的组件/版本更新
如果要在.NET Framework生态下解决这个问题,或者彻底避免它,有两个可行方向:
- 升级Visual Studio和C#编译器:升级到VS2019及以上版本,同时使用C# 8.0及以上的编译版本(VS2019默认支持C# 8.0)。新版编译器优化了匿名类型的动态访问逻辑,会生成允许DLR合法访问的代码,绕过权限限制。
- 切换到.NET Core/.NET 5+:如你测试的结果,这些新版本的.NET平台从底层修复了这个问题,直接迁移就能解决,不需要修改现有代码。
内容的提问来源于stack exchange,提问作者user3038144
相关产品推荐
相关产品推荐

