引言

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

dynamic 介绍

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

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

确保dynamic对象调用有效

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

比如以下代码:

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()方法,如下:

Person person = new Person();

var method = typeof(Person).GetMethod("MakeMoney");

int moneys = (int)method.Invoke(person, null);

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

dynamic person = new Person();

int moneys = person.MakeMoney();

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

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

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)时远小于使用反射实现的。

结论

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

编码技巧 --- 使用dynamic简化反射的更多相关文章

  1. 【dynamic】简化反射简单尝试

    最近在自己瞎整设计自己的数据访问层(纯属深入了解C#用),遇到了反射.网传反射性能很差,可是我们项目中也有功能用到了反射,总体来说还不错(小项目).由于居安思危的感觉越发沉重,不得不去打破传统,去寻求 ...

  2. 使用dynamic来简化反射实现

    dynamic是Framework4.0的新特性,dynamic的出现让C#具有了弱语言类型的特性,编译器在编译的时候,不再对类型进行检查,不会报错,但是运行时如果执行的是不存在的属性或者方法,运行程 ...

  3. 编写高质量代码改善程序的157个建议:使用Dynamic来简化反射的实现

    最近有时间看点书了,把157个建议在重新看一遍,代码都调试一遍.当我看到第15个建议的时候有些出入,就记录下来,欢迎大家来探讨. 第十五条建议是,使用dynamic简化反射的使用,没有说明具体的条件. ...

  4. 使用dynamic来简化反射实现,调用指定方法或构造函数

    dynamic是Framework4.0的新特性,dynamic的出现让C#具有了弱语言类型的特性,编译器在编译的时候,不再对类型进行检查,不会报错,但是运行时如果执行的是不存在的属性或者方法,运行程 ...

  5. 编写高质量代码改善C#程序的157个建议——建议15: 使用dynamic来简化反射实现

    建议15: 使用dynamic来简化反射实现 dynamic是Framework 4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译器默认dy ...

  6. 代码优化:Java编码技巧之高效代码50例

    出处:  Java编码技巧之高效代码50例 1.常量&变量 1.1.直接赋值常量值,禁止声明新对象 直接赋值常量值,只是创建了一个对象引用,而这个对象引用指向常量值. 反例: Long i = ...

  7. CSS编码技巧

    前面的话 本文将从DRY.currentColor.inherit和合理使用简写这几方面来详细介绍CSS编码技巧 DRY DRY,即don`t repeat yourself,尽量减少代码重复 在软件 ...

  8. [css 揭秘]:CSS编码技巧

    CSS编码技巧 我的github地址:https://github.com/FannieGirl/ifannie 喜欢的给我一个星吧 尽量减少代码重复 尽量减少改动时需要编辑的地方 当某些值相互依赖时 ...

  9. PHP编码技巧

    原则 正确实现功能 执行速度与快 占系统资源少 后期维护方便 编程注意 1.命名很重要 2.适当的使用注释 3.使用一个变量,需要初始化 4.优先使用单引号 $row['id']的效率是$row[id ...

  10. 01--css编码技巧--css揭秘

    一 尽量减少代码重复 1.按钮 #btn { padding: .3em .8em; border: 1px solid #446d88; background: #58a linear-gradie ...

随机推荐

  1. 在web浏览器中如何操作复合IC卡

    在web浏览器中如何操作复合IC卡呢, 对于使用javascript的工程师而言,非常简单,只需要几行代码即可实现.当然在写代码之前, 需要安装友我NFC读写器web插件, 然后插上NFC读写器YW- ...

  2. Django transaction.atomic 事务的使用

    函数 transaction.atomic 数据库的读写操作中,事务在保证数据的安全性和一致性方面起着关键的作用,而回滚正是这里面的核心操作. 遇到并发的时候常常会因为接口的访问顺序或者其他情况,导致 ...

  3. 2020-09-01:mysql里什么是检查点、保存点和中间点?

    福哥答案2020-09-01: 检查点checkpoint:批量刷盘.在一定程度上代表了刷到磁盘时日志所处的日志序列号(LSN)位置.标记重做日志中已经完成刷到磁盘的位置点,如果缓冲池中有很多重做日志 ...

  4. 2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中, 所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积,那么我们称它为 好子集 。 比方说,如果 nums =

    2022-10-23:给你一个整数数组 nums .如果 nums 的一个子集中, 所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积,那么我们称它为 好子集 . 比方说,如果 nums = ...

  5. 2020-11-25:go中,map的底层数据结构是什么?

    福哥答案2020-11-25: 简单回答:hmap映射头.bmap桶.mapextra溢出额外信息 中级回答: // 映射头 type hmap struct { // Note: the forma ...

  6. 2020-12-22:使用MQ的缺陷有哪些?

    福哥答案2020-12-22:系统可用性降低:以前只要担心系统的问题,现在还要考虑 MQ 挂掉的问题,MQ 挂掉,所关联的系统都会无法提供服务.系统复杂性变高:要考虑消息丢失.消息重复消费.消息顺序性 ...

  7. 2021-05-08:给定两个非负数组x和hp,长度都是N,再给定一个正数range。x有序,x[i]表示i号怪兽在x轴上的位置;hp[i]表示i号怪兽的血量 。range表示法师如果站在x位置,用A

    2021-05-08:给定两个非负数组x和hp,长度都是N,再给定一个正数range.x有序,x[i]表示i号怪兽在x轴上的位置:hp[i]表示i号怪兽的血量 .range表示法师如果站在x位置,用A ...

  8. mysql报错Unknown collation: utf8mb4_0900_ai_ci

    mysql报错Unknown collation: utf8mb4_0900_ai_ci 解决方案: 将文件内的所有 utf8mb4_0900_ai_ci 换成 utf8_general_ci utf ...

  9. Java 网络编程 —— 创建非阻塞的 HTTP 服务器

    HTTP 概述 HTTP 客户程序必须先发出一个 HTTP 请求,然后才能接收到来自 HTTP 服器的响应,浏览器就是最常见的 HTTP 客户程序.HTTP 客户程序和 HTTP 服务器分别由不同的软 ...

  10. Python asyncio之协程学习总结

    实践环境 Python 3.6.2 什么是协程 协程(Coroutine)一种电脑程序组件,该程序组件通过允许暂停和恢复任务,为非抢占式多任务生成子程序.协程也可以简单理解为协作的程序,通过协同多任务 ...