IT评测·应用市场-qidao123.com

标题: 编码技巧 --- 使用dynamic简化反射 [打印本页]

作者: 卖不甜枣    时间: 2023-7-24 12:41
标题: 编码技巧 --- 使用dynamic简化反射
引言

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

在C#中,dynamic是一种类型,它允许你在运行时动态地确定对象的类型。
使用dynamic类型可以使代码更加灵活,因为不需要在编译时知道对象的确切类型,而可以在运行时根据需要确定类型。
确保dynamic对象调用有效

但是正因为你不知道对象的确切类型,所以在编码时一定要注意,确保对象的类型和属性和方法的存在,否则代码可能会引发运行时异常。
比如以下代码:
  1. static void Main(string[] args)
  2. {
  3.     dynamic dynamicObject = new Person();
  4.    
  5.     var attr1 = dynamicObject.Name;
  6.    
  7.     var attr2 = dynamicObject.GetAge();
  8.     Console.ReadLine();
  9. }
  10. public class Person
  11. {
  12.     public string Gender { get; set; }
  13.    
  14.     public string Name { get; set; }
  15.    
  16.     public int MakeMoney()
  17.     {
  18.         return 200;
  19.     }
  20. }
复制代码
上述在编译时是不会报错的,但是在运行时,执行第二句是没问题的,因为得到的 dynamicObject 对象是有 Name ,Gender 两个属性的,但是执行第三句时就会抛出异常 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ,并提示 does not contain a definition for 'GetAge'。
dynamic 与 var

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

常规使用反射,调用上文中 Person 类 MakeMoney()方法,如下:
  1. Person person = new Person();
  2. var method = typeof(Person).GetMethod("MakeMoney");
  3. int moneys = (int)method.Invoke(person, null);
复制代码
那如果使用 dynamic 进行简化,则像这样:
  1. dynamic person = new Person();
  2. int moneys = person.MakeMoney();
复制代码
这样使用 dynamic 后,代码更简洁,而且也减少了一次拆箱操作。
基准测试工具 --- BenchmarkDotNet这篇文章中,介绍了使用 BenchmarkDotNet 来测试性能,接下来依然使用 BenchmarkDotNet 来测试以下,测试一下执行100000次,上述两种方式的区别:
  1. static void Main(string[] args)
  2. {
  3.     BenchmarkRunner.Run<BenchmarkTest>();
  4. }
  5. [SimpleJob(RunStrategy.ColdStart, iterationCount: 100000)]
  6. [MemoryDiagnoser]
  7. public class BenchmarkTest
  8. {
  9.     [Benchmark()]
  10.     public int UseReflection()
  11.     {
  12.         Person person = new Person();
  13.         var method = typeof(Person).GetMethod("MakeMoney");
  14.         int moneys = (int)method.Invoke(person, null);
  15.         return moneys;
  16.     }
  17.     [Benchmark()]
  18.     public int UseDynamic()
  19.     {
  20.         dynamic person = new Person();
  21.         int moneys = person.MakeMoney();
  22.         return moneys;
  23.     }
  24. }
复制代码
看一下 BenchmarkDotNet 测试结果,从报告中能看出来,使用 Dynamic 方式的方法的平均执行时间(Mean)和内存分配(AllLocated)时远小于使用反射实现的。

结论

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4