它说大多数高级动态类型语言是反身的。维基百科上的Reflection (computer programming)解释说,但它并没有真正清楚地说明它的含义。任何人都可以通过相关的例子以更简单的方式解释它吗?
答案 0 :(得分:4)
为您举例说明如何以实用的方式使用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在运行时动态加载资源。这可能有助于了解您可以使用它的方式。
查看此page以查看有关如何更详细地访问程序集的示例。这与我写的内容基本相同。
答案 1 :(得分:2)
为了更好地理解反思,想到一个评估程序的解释器。解释器是一个评估其他程序的程序。
程序可以(1)检查和(2)修改其(a)自己的状态/行为,或运行它的交互者的状态/行为(b)。
有四种组合。以下是各种行动的示例:
类型a称为结构反射。类型b称为行为反射。类型a的反映在语言中相当容易实现。 b型的反思更为复杂,尤其是2b--这是一个开放的研究课题。大多数人通过反思理解的是1a和2a。
了解具体化的概念以理解反思非常重要。当评估解释的程序中的语句时,解释器需要表示它。该解释器可能反对对要解释的程序的字段,方法等进行建模。毕竟,口译员也是一个程序。通过反射,解释的程序可以获得对解释器中表示其自身结构的对象的引用。这是具体化的。 (下一步是理解因果关系)
有各种各样的反光特征,有时会让人难以理解什么是反光的,是什么意思。从计划和口译的角度思考。我希望它能帮助您理解维基百科页面(可以改进)。
答案 2 :(得分:1)
Reflection是能够在运行时查询您编写的程序的元数据,例如:在程序集中找到哪些类,这些类包含哪些方法,字段和属性等等。
.net甚至包含'属性',这些是可以用类,方法,字段等装饰的类,它们的目的是添加您可以在运行时查询的自定义元数据。
许多时间细节仅取决于元数据。在验证时我们不关心字符串或int,但我们关心它不应该为null。因此,在这种情况下,您需要检查属性或属性,而无需关心特定的类。有反射出现在图片中。同样,如果你喜欢动态生成方法(在C#4.0的动态对象中可用),也可以使用反射。基本上它有助于做行为驱动或面向方面的编程。
另一种流行的用途是测试框架。他们使用反射来查找在代理环境中测试和运行它的方法。
答案 3 :(得分:0)
编程语言能够根据运行时信息调整其行为。 在.Net / C#世界中,经常使用它。 例如,在将数据序列化为xml时,可以添加一个属性来指定生成的xml中字段的名称。
答案 4 :(得分:0)
对于programmers.stackexchange.com来说,这可能是一个更好的问题。
但它基本上只是意味着您可以在代码中查看代码。
回到我的VB6时代,有一些UI对象具有Text属性,而其他UI对象具有Description(或者除了'Text'之外的其他东西,我忘了)。这是一个痛苦,因为我无法封装代码以同样的方式处理这两种对象。通过反射,我至少可以查看并查看对象是否具有Text或Description属性。
或者有时对象可能都具有Text属性,但它们派生自不同的基类,并且没有应用任何接口。同样,如果没有反射的帮助,很难将这样的代码封装在静态类型的语言中,但是即使是静态类型的语言也可以用反射来处理它。