2023-05-21
C#
00
请注意,本文编写于 287 天前,最后修改于 287 天前,其中某些信息可能已经过时。

目录

引言
dynamic 介绍
确保dynamic对象调用有效
dynamic 与 var
使用 dynamic 简化反射
结论

引言

dynamicFramework 4.0 就出现特性,它的出现让 C# 具有了弱语言类型的特性。编译器在编译的时候不再对类型进行检查,默认 dynamic 对象支持开发者想要的任何特性。

dynamic 介绍

在C#中,dynamic是一种类型,它允许你在运行时动态地确定对象的类型。

使用dynamic类型可以使代码更加灵活,因为不需要在编译时知道对象的确切类型,而可以在运行时根据需要确定类型。

确保dynamic对象调用有效

但是正因为你不知道对象的确切类型,所以在编码时一定要注意,确保对象的类型和属性和方法的存在,否则代码可能会引发运行时异常。

比如以下代码:

csharp
static void Main(string[] args) { dynamic dynamicObject = new Person(); var attr1 = dynamicObject.Name; var attr2 = dynamicObject.GetAge(); Console.ReadLine(); } public class Person { public string Gender { get; set; } public string Name { get; set; } public int MakeMoney() { return 200; } }

上述在编译时是不会报错的,但是在运行时,执行第二句是没问题的,因为得到的 dynamicObject 对象是有 NameGender 两个属性的,但是执行第三句时就会抛出异常 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ,并提示 does not contain a definition for 'GetAge'

dynamic 与 var

有时候会将 var 关键字与 dynamic 进行对比,那么我觉得主要有以下几点:

  1. var 用于在编译时推断变量类型,可以将其视为一种简写方式,将变量类型的声明推迟到编译时。而 dynamic 则是一种在运行时动态确定对象类型的类型。它允许您在运行时调用对象的属性和方法,而不需要在编译时确定对象的确切类型。
  2. var声明的变量在Visual Studio编译器中能够使用IntelliCode进行“智能提示”,因为Visual Studio编译器在此阶段是可以推断出其实际类型,而dynamic 类型的变量不可以进行”智能提示“。
  3. var 类型的变量可以使代码更加简洁和易于阅读,而使用 dynamic 类型的变量则可以使代码更加灵活和动态。

使用 dynamic 简化反射

常规使用反射,调用上文中 PersonMakeMoney()方法,如下:

csharp
Person person = new Person(); var method = typeof(Person).GetMethod("MakeMoney"); int moneys = (int)method.Invoke(person, null);

那如果使用 dynamic 进行简化,则像这样:

csharp
dynamic person = new Person(); int moneys = person.MakeMoney();

这样使用 dynamic 后,代码更简洁,而且也减少了一次拆箱操作。

基准测试工具 --- BenchmarkDotNet这篇文章中,介绍了使用 BenchmarkDotNet 来测试性能,接下来依然使用 BenchmarkDotNet 来测试以下,测试一下执行100000次,上述两种方式的区别:

csharp
static void Main(string[] args) { BenchmarkRunner.Run<BenchmarkTest>(); } [SimpleJob(RunStrategy.ColdStart, iterationCount: 100000)] [MemoryDiagnoser] public class BenchmarkTest { [Benchmark()] public int UseReflection() { Person person = new Person(); var method = typeof(Person).GetMethod("MakeMoney"); int moneys = (int)method.Invoke(person, null); return moneys; } [Benchmark()] public int UseDynamic() { dynamic person = new Person(); int moneys = person.MakeMoney(); return moneys; } }

看一下 BenchmarkDotNet 测试结果,从报告中能看出来,使用 Dynamic 方式的方法的平均执行时间(Mean)和内存分配(AllLocated)时远小于使用反射实现的。

image.png

结论

在相同数量级的反射实现和使用 Dynamic 方式实现, Dynamic 方式在执行时间或内存分配或代码简洁都是有优势的,所以推荐使用 dynameic 来简化反射实现

本文作者:Peter.Pan

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!