什么是编程语言的Reflection属性?

它说大多数高级动态类型语言是反身的。 维基百科上的反思(计算机编程)解释说,但它并没有真正给出它的含义。 任何人都可以通过相关的例子以更简单的方式解释它吗?

为您举例说明如何以实用的方式使用Reflection:

假设您正在开发一个您希望使用插件扩展的应用程序。 这些插件是简单的Assemblies,只包含一个名为Person的类:

namespace MyObjects { public class Person { public Person() { ... Logic setting pre and postname ... } private string _prename; private string _postname; public string GetName() { ... concat variabes and return ... } } } 

好吧,插件应该在运行时扩展您的应用程序。 这意味着,当您的应用程序已经运行时,应该从另一个程序集加载内容和逻辑。 这意味着这些资源不会编译到您的程序集中,即MyApplication.exe。 让我们假设它们位于库中:MyObjects.Person.dll。

您现在面临的事实是,您需要提取此信息,例如从MyObjects.Person访问GetName()函数。

 // Create an assembly object to load our classes Assembly testAssembly = Assembly.LoadFile(Application.StartUpPath + @"MyObjects.Person.dll"); Type objType = testAssembly.GetType("MyObjects.Person"); // Create an instace of MyObjects.Person var instance = Activator.CreateInstance(objType); // Call the method string fullname = (string)calcType.InvokeMember("GetName", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, instance, null); 

如您所见,您可以使用System.Reflection在运行时动态加载资源。 这可能有助于了解您可以使用它的方式。

查看此页面以查看有关如何更详细地访问程序集的示例。 这与我写的内容基本相同。

为了更好地理解反思,请考虑一个评估程序的解释器 。 解释器是一个评估其他程序的程序。

该程序可以(1)检查和(2)修改其(a)自己的状态/行为,或运行它的交互者的状态/行为(b)。

然后有四种组合。 以下是每种操作的示例:

  • 1a – 读取对象所具有的字段列表
  • 2a – 根据字段名称修改一个字段的值; 反思性的方法调用。
  • 1b – 检查当前堆栈以了解当前执行的方法是什么
  • 2b – 修改堆栈或如何执行语言中的某些操作(例如,消息发送)。

类型a称为结构reflection。 b型称为行为reflection。 类型a的反映在语言中相当容易实现。 b型的反思更为复杂,尤其是2b–这是一个开放的研究课题。 大多数人通过反思理解的是1a和2a。

重要的是要理解具体化的概念以理解反思。 当评估解释的程序中的语句时,解释器需要表示它。 该解释器可能反对对要解释的程序的字段,方法等进行建模。 毕竟,口译员也是一个程序。 通过reflection,解释的程序可以获得对解释器中表示其自身结构的对象的引用。 这是具体化的。 (下一步是理解因果关系

有各种各样的reflection特征,有时候很难理解什么是reflection性的,以及它的含义。 从程序和口译的角度思考。 我希望它能帮助您理解维基百科页面(可以改进)。

reflection是能够在运行时查询您编写的程序的元数据,例如:在程序集中找到哪些类,这些类包含哪些方法,字段和属性等等。

.net甚至包含“属性”,这些类可以用类,方法,字段等来装饰,而且它们的目的是添加可以在运行时查询的自定义元数据。

许多时间细节仅取决于元数据。 在validation时我们不关心字符串或int,但我们关心它不应该为null。 因此,在这种情况下,您需要检查属性或属性,而无需关心特定的类。 有reflection出现在图片中。 同样,如果你想快速生成方法(在C#4.0的动态对象中可用),也可以使用reflection。 基本上它有助于执行行为驱动或面向方面编程。

另一个流行的用途是测试框架。 他们使用reflection来查找在代理环境中测试和运行它的方法。

编程语言能够根据运行时信息调整其行为。 在.Net / C#世界中,经常使用它。 例如,在将数据序列化为xml时,可以添加一个属性来指定生成的xml中字段的名称。

对于programmers.stackexchange.com来说,这可能是一个更好的问题。

但它基本上只是意味着您可以在代码中查看代码。

回到我的VB6时代,有一些UI对象具有Text属性,而其他UI对象具有Description(或者除了’Text’之外的其他东西,我忘了)。 这是一个痛苦,因为我无法封装代码以同样的方式处理这两种对象。 通过reflection,我至少可以查看并查看对象是否具有Text或Description属性。

或者有时对象可能都具有Text属性,但它们派生自不同的基类,并且没有应用任何接口。 同样,如果没有reflection的帮助,很难将这样的代码封装在静态类型的语言中,但是即使是静态类型的语言,也可以使用reflection来处理它。