您当前的位置: 首页 >  c#

寒冰屋

暂无认证

  • 3浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C#中反射和动态关键字有什么区别?

寒冰屋 发布时间:2021-09-23 15:03:47 ,浏览量:3

目录

介绍

什么是反射以及我们为什么需要它?

我们如何实现反射?

第1步

第2步

反射的实际用途是什么?

Dynamic关键字的用途是什么?

Dynamic关键字的实际用途是什么?

反射和Dynamic有什么区别?

介绍

在本文中,我们将尝试理解两个术语:反射和dynamic关键字。许多开发人员对它们感到困惑,因为它们都帮助我们进行动态调用。

在本文中,我们将尝解释差异,看看我们将在哪些场景中使用她们。不过在开始对比之前,我们先分别了解一下,然后在文章的最后再做一个全面的对比。

什么是反射以及我们为什么需要它?

当您要确定/检查程序集的内容时需要反射。例如,当您在任何对象之前键入“.” (dot)时,查看您的Visual Studio编辑器智能感知,它为您提供该对象的所有成员。由于反射,这是可能的。

 

反射也更进了一步;它还可以调用被检查的成员。例如,如果反射检测到对象中调用了一个GetChanges方法,我们可以获取对该方法实例的引用并在运行时调用它。

简单来说,反射经过两个步骤:“Inspect ”和“Invoke”(可选)。“Invoke”过程是可选的。

 

 

我们如何实现反射?

在C#中实现反射是一个两步过程,首先获取对象的“类型”,然后使用类型浏览“方法”、“属性”等成员。

第1步

第一步是获取对象的类型。因此,例如,您有一个DLL ClassLibrary1.dll,它有一个名为Class1的类。 我们可以使用Assembly(属于System.Reflection命名空间)类来获取对对象类型的引用。稍后,我们可以使用Activator.CreateInstance创建类的实例。该GetType()函数帮助我们获取对对象类型的引用。

var myAssembly = Assembly.LoadFile(@"C:\ClassLibrary1.dll");
var myType = myAssembly.GetType("ClassLibrary1.Class1");
dynamic objMyClass = Activator.CreateInstance(myType);
// Get the class type
Type parameterType = objMyClass.GetType();

第2步

一旦我们获得了对象类型的引用,我们就可以调用GetMembers或GetProperties浏览类的方法和属性。

// Browse through members
foreach (MemberInfo objMemberInfo in parameterType.GetMembers())
{Console.WriteLine(objMemberInfo.Name);}

// Browse through properties.
foreach (PropertyInfo objPropertyInfo in parameterType.GetProperties())
{Console.WriteLine(objPropertyInfo.Name);}

如果要调用已检查的成员,可以使用InvokeMember来调用该方法。下面是代码:

parameterType.InvokeMember("Display",BindingFlags.Public | 
BindingFlags.NonPublic | BindingFlags.InvokeMethod | 
BindingFlags.Instance,null, objMyClass, null); 

反射的实际用途是什么?
  • 如果您正在创建像Visual Studio编辑器这样的应用程序,您希望在其中使用智能感知显示对象的内部结构。
  • 如果您正在创建单元测试框架。在单元测试框架中,我们需要动态调用方法和属性以进行测试。
  • 有时我们希望将属性、方法和程序集引用转储到文件或在屏幕上显示。
Dynamic关键字的用途是什么?

编程语言可以分为两类:强类型和动态类型。强类型语言是在编译时进行检查的语言,而动态语言是在编译时绕过类型检查的语言。在动态语言中,对象类型仅在运行时已知,类型检查仅在运行时激活。

 

我们想利用这两个类型。因为很多时候,直到执行代码我们才知道对象类型。换句话说,我们正在研究类似动态和静态类型的环境。这就是dynamic关键字对我们的帮助。

如果您使用dynamic关键字创建变量并尝试查看该对象的成员,您将收到如下所示的消息“将在运行时解析”。

 

现在试试下面的代码。在代码中,我创建了一个用string数据初始化的dynamic变量。在第二行中,我试图通过尝试执行数字增量操作来获得乐趣。那么现在会发生什么呢?思考....

dynamic x = "c#";
x++;

现在这段代码将编译得很好,没有任何抱怨。但是在运行时,它会抛出一个异常,抱怨无法对变量执行数学运算,因为它是字符串类型。换句话说,在运行时,dynamic对象从通用数据类型转换为特定数据类型(例如:对于下面的string代码)。

 

 

Dynamic关键字的实际用途是什么?

该dynamic关键字最大的实际用途之一是当我们通过互操作操作MS Office组件时。

因此,例如,如果我们在没有dynamic关键字的情况下访问Microsoft Excel组件,您可以看到代码变得多么复杂。在下面的代码中发生了很多转换,对吧?

// Before the introduction of dynamic.
Application excelApplication = new  Application();
((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name";
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];

现在看看使用dynamic关键字使代码变得多么简单。不需要强制转换,并且在运行时类型检查也会发生。

// After the introduction of dynamic, the access to the Value property and 
// the conversion to Excel.Range are handled by the run-time COM binder.
dynamic excelApp = new Application();
excelApp.Cells[1, 1].Value = "Name";
Excel.Range range2010 = excelApp.Cells[1, 1];

反射和Dynamic有什么区别?
  • 当我们想要在运行时对对象进行操作时,可以使用Reflection和dynamic。
  • 反射用于检查对象的元数据。它还具有在运行时调用对象成员的能力。
  • dynamic是.NET 4.0中引入的关键字。它在运行时评估对象调用。因此,在进行方法调用之前,编译器最不关心这些方法/属性是否存在。
  • dynamic在内部使用反射。它缓存了所做的方法调用,从而在一定程度上提高了性能。
  • 反射可以同时调用对象的public和private成员,而dynamic只能调用public成员。
  • dynamic是特定于实例的:您无权访问static成员;你必须在这些场景中使用反射。

下面是详细的比较表,显示了它们适用于哪种场景:

 

反射

Dynamic

检查(元数据)

调用公共成员

调用私有成员

缓存

静态类

下面是一个简单的图表,它直观地总结了Reflection可以做什么以及dynamic关键字可以做什么。

 

https://www.codeproject.com/Articles/593881/What-is-the-Difference-between-Reflection-and-Dyna

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0453s