你可以使用 dynamic
来定义一个变量或者字段,随后你可以像弱类型语言一样调用这个实例的各种方法,就像你一开始就知道这个类型的所有属性和方法一样。
但是,使用不当又会遇到各种问题,本文收集使用过程中可能会遇到的各种问题,帮助你解决掉它们。
快速入门
dynamic
可以这么用:
1 2 3 4 5 6 7 | dynamic foo = GetSomeInstance(); foo.Run("欢迎访问吕毅(lvyi)的博客:blog.walterlv.com"); object GetSomeInstance() { return 诡异的东西; } |
---|
我们的 GetSomeInstance
明明返回的是 object
,我们却可以调用真实类中的方法。
接下来讲述使用 dynamic
过程中可能会遇到的问题和解决方法。
编译错误:缺少编译器要求的成员
你初次在你的项目中引入 dynamic
关键字后,会出现编译错误,提示 “缺少编译器要求的成员”。
error CS0656: 缺少编译器要求的成员“Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create”
对于 .NET Core 或者 .NET Standard 项目
需要为你的项目安装以下两个 NuGet 包:
- Microsoft.CSharp
- System.Dynamic.Runtime
于是你的项目里面会多出两个引用:
1 2 3 4 5 6 7 8 9 10 11 12 | <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks>netstandard2.0;net48</TargetFrameworks> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CSharp" Version="4.5.0" /> <PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" /> </ItemGroup> </Project> |
---|
对于 .NET Framework 项目
你需要引用 Microsoft.CSharp
:
于是你的项目里面会多出一项引用:
1 2 3 4 5 6 7 8 9 10 11 | <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> <PropertyGroup> <TargetFramework>net48</TargetFramework> </PropertyGroup> <ItemGroup> <Reference Include="Microsoft.CSharp" /> </ItemGroup> </Project> |
---|
异常:“{0}”未包含“{1}”的定义
{0}
是类型名称,而 {1}
是使用 dynamic
访问的属性或者方法的名称。
比如,我试图从某个 Attribute
中访问到 Key
属性的时候会抛出以下异常:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:““System.Attribute”未包含“Key”的定义”
出现此异常的原因是:
dynamic
所引用的对象里面,没有签名相同的public
的属性或者方法
于是,如果你确认你的类型里面是有这个属性或者方法的话,那么就需要注意需要将此成员改成 public
才可以访问。
参考资料
- c# - Why a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException if the invoked method is there? - Stack Overflow
本文会经常更新,请阅读原文: https://blog.walterlv.com/post/problems-when-using-csharp-dymanic-binding.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。