|
1
24
反射是一种功能,您可以在运行时查询对象的属性。例如,Python、Java和.NET具有可以找到对象的实例变量或方法的工具。 反射应用程序的一个例子是O/R映射层。有些使用反射来构造对象,方法是在运行时查询其属性并动态填充实例。这允许您根据某种数据字典中的元数据进行编程,而无需重新编译应用程序。 举一个简单的例子,我将使用Python,因为它的反射设备使用起来非常简单,并且涉及到比Java或.NET的更少的样板。
现在,我们使用基本反射来检查任意对象的实例变量。特殊变量
注意,这个特定的技巧在Java或.NET上不起作用,因为实例变量是固定的。这些语言的类型系统不允许在运行时像Python的“duck”类型系统那样添加新的实例变量。但是,您可以反射性地更新类型定义中声明的实例变量的值。 您还可以使用反射动态地构造方法调用,并执行各种其他简单的技巧,例如基于参数实例化对象。例如,如果您有某种基于插件的系统,其中某些功能是可选的,那么您可以使用反射来查询插件提供的服务(可能通过查询某些接口是否实现),而不需要显式元数据。 许多动态语言接口(如OLE自动化)使用反射作为接口的一个组成部分。 |
|
|
2
20
没什么大不了的 修改 在执行时执行代码,但检查对象并要求它们在不静态了解其类型的情况下执行代码。 描述它的一个简单方法是“使静态类型语言动态运行的一种有点痛苦的方法”。 编辑:用途:
这是个好主意吗?好吧,只有在选择是痛苦的时候。我更喜欢静态类型,当它不妨碍的时候-然后你会得到很多编译时的好处,而且速度也更快。但是当你 做 需要它,反思让你做各种事情,否则就是不可能的。 |
|
|
3
3
我能想到的第一个很好的例子是,当你需要在一个给定的对象上执行一组方法而不知道在编译时会有什么方法存在的时候。
以单元测试框架为例。负责运行所有单元测试的测试运行程序类不会提前知道您要命名的方法。它所知道的是,它们将被前缀“test”(或在Java 5的情况下,注释)。
|
|
|
4
3
在我能想到的至少一个项目中,思考对我很有用。我们编写了一个内部“流程管理器”程序,在特定的时间间隔内执行许多关键业务流程。这个项目的建立使得核心实际上只是一个Windows服务,它的计时器对象每隔30秒左右就会触发一次,并检查要做的工作。 实际工作是在类库中完成的(适当地称为“workerlib”)。我们用执行特定任务的公共方法定义类(移动文件、将数据上载到远程站点等),其思想是核心服务可以从工作库调用方法,而不知道它调用的方法。这允许我们在数据库中为作业创建一个时间表,甚至可以在不必更改核心系统的情况下将新方法添加到类库中。 基本思想是,我们可以在核心服务中使用反射来执行方法,这些方法的名称存储在定义调度的数据库中。它在实践中非常整洁。我们的核心服务是可靠的,可以根据需要执行任务,而实际的工人图书馆可以根据需要进行扩展和更改,而无需核心甚至关怀。 如果您需要进一步解释,请随时询问。这只是我能想到的最好的解释现实世界场景的方法,在这个场景中,反思真的让事情变得更容易。 |
|
|
5
2
另一个示例:我使用的代码获取数据库的输出(这是一组具有命名列的行),并将其馈送到对象数组中。我迭代这些行,如果目标对象有一个具有相同名称和类型的属性,我就设置它。这使得我的数据获取代码看起来像这样:
|
|
|
6
2
实际上,反射应该被认为是一种代码放大器。它可以使好的代码更好、更干净,坏的代码更糟。它是做什么的?它确实允许您编写代码,您不完全确定在编写代码时要做什么。您有一个一般的想法,但是它不允许您在编译程序时对要执行的对象、方法和属性进行编码。 其他文章说它允许程序根据配置值执行代码是正确的,但真正的力量是它允许您严重地弯曲面向对象编程的规则。这就是它真正的作用。这有点像关闭安全措施。私有方法和属性可以通过反射和其他任何方法访问。 MS使用反射的一个很好的例子是数据对象上的数据绑定。为要绑定到下拉列表等的对象指定文本字段和数据字段的名称,代码反映对象并提取适当的信息。数据绑定对象一次又一次地执行相同的过程,但它不知道必须与哪种类型的对象绑定。反射是编写少量代码以处理所有可能的情况的一种方便方法。 |
|
7
1
在Java中,它基本上是一种在事先不知道它的情况下实例化类的方法。假设您希望用户能够通过添加希望程序使用的类来更改配置文件(假设您有许多接口实现)。通过反射,您可以基于对象的名称、方法签名等创建对象。,然后将其转换到您的接口。 |
|
|
8
1
反射对于运行时配置很有用,它允许通过外部配置驱动系统的某些部分。 例如,类工厂可以基于输入文件构造不同的具体类型,其中具体类型需要不同的配置信息来调用具体的构造函数,而不是使用生成器接口。(使用反射定位的对象的构造函数方法)。 |
|
9
1
反射是(基本上)程序查询编译器可用类型信息的能力。例如,给定一个类型的名称,就可以查询它包含的方法。然后,对于每个方法,您可以查询它们所采用的参数类型等。 它对于运行时配置很有用,因为在运行时配置文件中指定了应用程序的行为。配置可能包含您应该使用的具体类型的名称(IOC容器通常也是这样)。使用反射,您可以创建此具体类型的实例(通过反射API)并使用它。 |
|
10
1
我给你举个例子。 作为编程练习,我写了一个MP3文件检查程序。它扫描我的音乐库并显示我对DataGridView感兴趣的ID1/ID2标记。我使用反射从mp3信息类中获取属性,而不需要让UI代码知道关于该类的任何信息。如果要更改显示的信息,可以编辑MP3信息类或更改其配置(取决于我如何编写该类),而不必更新UI。 这也意味着我可以通过交换数据库类,使用依赖注入来从末尾使用相同的内容来显示有关数字照片的信息。 |
|
|
11
1
程序集包含模块,模块包含类型,类型包含成员。反射提供封装程序集、模块和类型的对象。可以使用反射动态创建类型的实例、将类型绑定到现有对象或从现有对象获取类型。然后可以调用类型的方法或访问其字段和属性。反射的典型用途包括:
|
|
|
Theo Walton · 初始化静态成员使编译工作正常。。。但为什么 8 年前 |
|
|
vik santata · 如何在Haskell中编写具有初始条件的递归函数? 10 年前 |
|
|
Max Herrmann · 内联值的定义 10 年前 |
|
|
Wyllow Wulf · 要在项目Visual C中使用的函数定义++ 10 年前 |
|
|
user3437460 · 使用CSS在多个表上设置字体财产 12 年前 |