首页 > 其他分享 >编码技巧 --- 使用dynamic简化反射

编码技巧 --- 使用dynamic简化反射

时间:2023-07-24 14:13:28浏览次数:45  
标签:编码 int dynamic --- Person 类型 var

合集 - c#基础(7)   1.编码技巧 --- 如何实现字符串运算表达式的计算07-122.编码技巧 --- 同步锁对象的选定07-133.解读 --- yield 关键字07-174.并发编程 --- 信号量线程同步07-185.并发编程 ---为何要线程池化07-186.编码技巧 --- 谨防闭包陷阱07-19 7.编码技巧 --- 使用dynamic简化反射07-24 收起  

引言

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

image.png

结论

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

 

 

出处:https://www.cnblogs.com/pandefu/p/17536271.html

标签:编码,int,dynamic,---,Person,类型,var
From: https://www.cnblogs.com/mq0036/p/17577054.html

相关文章

  • 实操-实用指令
    运行级别改默认运行级别找回root密码--单用户帮助指令Linux下,隐藏文件是以.开头的;选项可以组合使用,比如:ls-la/-al(-l是按列输出,-a是所有文件,会把隐藏文件也输出)文件目录类*rm-rf   谨慎使用cp移动后面加上名字就是移动并重命名;仅查看,所以更安全;......
  • Python【18】 pytorch中的one_hot() (独热编码函数)
    参考:https://pytorch.org/docs/stable/generated/torch.nn.functional.one_hot.html......
  • vue项目使用vue-virtual-scroll-list虚拟滚动超多千万条数据 cv可用案例
    当我们有大量数据需要显示在列表中时,传统的滚动列表会将所有数据渲染到DOM中,导致性能下降和内存占用增加。虚拟滚动列表通过仅渲染当前视窗内可见的一小部分数据,动态地根据滚动位置更新列表内容,从而实现更高效的列表渲染。vue-virtual-scroll-list是一个用于Vue.js的虚拟滚动......
  • m基于DVB-T的COFDM+16QAM+LDPC码通信链路matlab性能仿真,包括载波同步,定时同步,信道
    1.算法仿真效果matlab2022a仿真结果如下:包括小数倍及整数倍载波同步,粗及细定时同步2.算法涉及理论知识概要基于DVB-T的COFDM+16QAM+LDPC码通信链路是一种常用的数字视频广播系统,用于实现高效的传输和接收。该系统结合了正交频分复用(COFDM)、16QAM调制和低密度奇偶校验(LDPC)编码......
  • 【WebGL系列-01】获取WebGL上下文
    获取WebGL上下文获取上下文WebGL上下文是从<canvas>标签中获取到的,通过canvas对象的getContext()函数可以获取WebGLRenderingContext。跟据参数的不同,getContext()函数可以获取不同种类的渲染上下文。接口canvas.getContext(contextType:String,contextAttributes?:Objec......
  • 【WebGL系列-02】创建program上下文
    WebGL程序program对象的创建program对象由顶点着色器对象和片元着色器对象构成,因此,创建program对象包含了两部分,一个是着色器对象的创建,一个是program对象的创建。总体流程创建顶点着色器对象创建片元着色器对象创建program对象将顶点着色器和片元着色器添加到程序中将程......
  • 【WebGL系列-03】获取shader变量地址及赋值
    获取shader变量地址及赋值上一节创建了WebGL程序对象,创建好program对象后,对象中包含顶点着色器和片元着色器,着色器中含有变量,我们需要对其进行赋值后才能够进行绘制。着色器代码如下:constVSHADER_SOURCE=/*glsl*/`attributevec4a_Position;voidmain(){gl_P......
  • 【WebGL系列-04】清除缓冲区并绘制图形
    清除缓冲区并绘制图形前文中已经准备好了webgl程序和绘制所用的数据,但是在绘制图像之前,还要对画布进行处理。清除缓冲区由于图像的绘制是一帧一帧绘制,每一帧针对当前的状态,计算屏幕上每个像素的颜色,得到最终的绘制结果。这些状态被保存在一个叫帧缓冲区的地方。帧缓冲区不仅能......
  • m基于DVB-T的COFDM+16QAM+LDPC码通信链路matlab性能仿真,包括载波同步,定时同步,信道
    1.算法仿真效果matlab2022a仿真结果如下: 包括小数倍及整数倍载波同步,粗及细定时同步     2.算法涉及理论知识概要        基于DVB-T的COFDM+16QAM+LDPC码通信链路是一种常用的数字视频广播系统,用于实现高效的传输和接收。该系统结合了正交频分复用(CO......
  • 无涯教程-之后(内容)
    after(content)方法在每个匹配的元素之后插入内容。after(content)-语法selector.after(content)这是此方法使用的所有参数的描述-content  - 在每个目标后面插入的内容。这可能是HTML或文本内容after(content)-示例以下是一个简单的示例,简单说明了此方法......