C#用dynamic一行代码实现反射操作
Posted .NET100
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#用dynamic一行代码实现反射操作相关的知识,希望对你有一定的参考价值。
dynamic简介
dynamic是.NET Framework4.0的新特性。dynamic的出现让C#具有了弱语言类型的特性。编译器在编译的时候不再对类型进行检查,编译时默认dynamic对象支持你想要的任何特性。
dynamic简化反射实现
使用dynamic来简化反射实现是一种比较常见的编程技巧,它可以减少代码的复杂性并提高可读性。下面是一个使用dynamic来简化反射实现的示例:
// 定义一个类
public class Person
public string Name get; set;
public int Age get; set;
public string Gender get; set;
// 创建一个对象并设定属性值
var person = new Person
Name = "刘备",
Age = 30,
Gender = "男"
;
// 使用反射获取属性值
var type = person.GetType();
var properties = type.GetProperties();
foreach (var property in properties)
var value = property.GetValue(person);
Console.WriteLine($"property.Name:value");
// 使用dynamic来简化反射实现
dynamic dynamicPerson = person;
Console.WriteLine($"Name:dynamicPerson.Name, Age:dynamicPerson.Age, Gender:dynamicPerson.Gender");
//欢迎公众号:DOTNET开发跳槽,领取海量面试题
可以看到,使用dynamic来简化反射实现可以将代码变得更加简洁易读,同时也可以避免一些繁琐的反射操作。使用dynamic可能会带来一些性能上的损失,应该根据具体情况进行选择。具体会不会,下面实验一下。
dynamic与反射的性能对比
这里首先新建一个类和一个两数相加的方法,然后分别使用反射和dynamic来调用这个类的方法,并循环数次,来对比它们的性能。代码如下:
#region 反射和dynamic的对比
int times = 1000000;
DynamicTest reflectTest = new DynamicTest();
var addMethod = typeof(DynamicTest).GetMethod("Add");
Stopwatch watchl = Stopwatch.StartNew();
for (var i = 0;i< times; i++)
addMethod.Invoke(reflectTest, new object[] 1, 2 );
Console.WriteLine($"反射耗时:watchl.ElapsedMilliseconds毫秒");
dynamic dynamicTest = new DynamicTest();
Stopwatch watch2 = Stopwatch.StartNew();
for (int i =0;i< times; i++)
dynamicTest.Add(1,2);
Console.WriteLine($"dynamic耗时:watch2.ElapsedMilliseconds 毫秒");
#endregion
//测试的类
public class DynamicTest
public string Nameget; set;
public int Add(int a, int b)
return a + b;
//欢迎公众号:DOTNET开发跳槽,领取海量面试题
100万次的效果:
1万次的效果:
可见100万次循环的效果dynamic要好点,1万次反射耗时小于dynamic。为了效果,所以每一次实验运行两次。
结语
由上可以看出dynamic的确可以简化反射,让代码更加简洁,可读性更强。但是从对比来看,dynamic在低数量调用的使用上性能要比反射弱太多,比较大的数量调用来说它们不相上下。建议如果你的代码对性能要求不太高的情况下,可以使用dynamic来简化反射。
参考:微软官方文档,《改善C#程序的157个建议》
来源公众号:DotNet开发跳槽
C# 反射类Assembly用法举例
概述
程序运行时,通过反射可以得到其它程序集或者自己程序集代码的各种信息,包括类、函数、变量等来实例化它们,执行它们,操作它们,实际上就是获取程序在内存中的映像,然后基于这个映像进行各种操作。
Assembly介绍
Assembly类即程序集类,用来加载其他程序集,加载后可以用Type来使用其他程序集中的信息,如果想要使用其它程序集中的内容,需要先加载程序集。
加载程序集的三种方法:
①、一般用来加载同一文件下的其他程序集
Assembly assembly = Assembly.Load(“AssemblyName”);
②、一般用来加载不再同一文件下的其他程序集
Assembly assembly = Assembly.LoadFrom(“包含程序集清单的文件的名称或路径”);
Assembly assembly = Assembly.LoadFile(“要加载的文件的完全限定路径”);
使用方法:
Assembly asm = Assembly.LoadFrom("Demo.dll");//需要加后缀,可以指定路径,如:Assembly.LoadFrom(@"C:\\Users\\majm\\source\\repos\\ConsoleApp29\\bin\\Debug\\TestDll.dll");
Assembly asm = Assembly.Load("Demo");//无需加后缀,不可以指定路径,
使用Load可以加载当前程序bin目录行下的程序集或者系统程序集
定义数据模型:创建类库并生成dll
namespace TestDll
public class Person
public Person()
Name = "zls";
Age = 18;
id = 20;
public Person(string name, int age)
Name = name;
Age = age;
id = 21;
public string Name get; set;
public int Age get; set;
public int id;
public int Score(int a, int b)
return a + b;
第一步:首先加载一个指定程序集:
Assembly assembly = Assembly.LoadFrom(@"C:\\Users\\majm\\source\\repos\\ConsoleApp29\\bin\\Debug\\TestDll.dll");
Type[] types = assembly.GetTypes();
for (int i = 0; i < types.Length; i++)
Console.WriteLine(types[i]);
运行结果:
第二步:加载程序集中类对象:并调用方法传入参数
Type c1 = types[0];
object obj = Activator.CreateInstance(c1);
//调用Class1类中的Speak方法
MethodInfo speak = c1.GetMethod("Score");
object[] o = new Object[2] 12,13 ;
var result = speak.Invoke(obj, o);
Console.WriteLine(result);
运行结果:25
这里还可以这样如下去创建实例:
Type c1 = types[0];
Assembly asm = Assembly.GetAssembly(c1);
Person person = (Person)asm.CreateInstance("TestDll.Person", true);//true:不区分大小写
//调用Person1类中的Score方法
MethodInfo speak = c1.GetMethod("Score");
object[] o = new Object[2] 12,13 ;
var result = speak.Invoke(person, o);
Console.WriteLine(result);
一样的效果,如果是当前程序集,可以GetExecutingAssembly获取程序集
Assembly asm = Assembly.GetExecutingAssembly();
以上是关于C#用dynamic一行代码实现反射操作的主要内容,如果未能解决你的问题,请参考以下文章
Dynamics 365中使用JavaScript和C#调用操作示例