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

目录

介绍

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

 我们如何实现反射?

第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

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

// 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有什么区别?

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

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

 

反射

Dynamic

检查(元数据)

调用公共成员

调用私有成员

缓存

静态类

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#反射是指在运行时动态地获取类型信息、访问属性和调用方法的能力。通过反射,我们可以在运行时检查类型信息、创建实例、调用方法、访问属性和字段等。使用反射可以实现一些动态的操作,比如在不知道类型的情况下调用其方法或者访问其属性。 要使用反射获取类型信息和调用方法,可以按照以下步骤进行: 1. 获取类型信息:使用`Type`类可以获取类型的信息,比如获取类型的名称、方法、属性等。可以使用`typeof`关键字获取已知类型的信息,也可以使用`GetType()`方法获取对象的类型信息。 2. 创建实例:使用反射可以动态创建类型的实例,可以使用`Activator.CreateInstance`方法来创建对象。 3. 调用方法:使用`MethodInfo`类可以获取方法的信息,然后使用`Invoke`方法来调用方法。 下面是一个简单的示例,演示如何使用反射获取类型信息和调用方法: ```csharp using System; using System.Reflection; public class MyClass { public void MyMethod() { Console.WriteLine("Hello from MyMethod!"); } } public class Program { public static void Main() { Type type = typeof(MyClass); object instance = Activator.CreateInstance(type); MethodInfo methodInfo = type.GetMethod("MyMethod"); methodInfo.Invoke(instance, null); } } ``` 在上面的示例,我们首先获取`MyClass`的类型信息,然后使用`Activator.CreateInstance`创建了一个`MyClass`的实例。接着,我们获取了`MyMethod`方法的信息,并使用`Invoke`方法调用了该方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值