使用.NET反射来访问私有方法。为什么这样做?

3

以前我在公共方法上多次使用过反射,但我从未意识到私有方法也可以被调用。请参见Reflection with private members

为什么会允许这样做呢?这不会违反“私有”就意味着“私有”的规则吗?


那个链接已经失效了。它是否移动到其他地方了? - Peter Mortensen
5个回答

4
在C#中,private实际上只是语言规范的一部分;在C#语言以及Visual Basic语言或任何其他合理的.NET语言(包括所有.NET语言编译成的CIL)中,通过语言是无法访问private(或protected,如果您不在派生类中)成员的。然而,仅仅因为语言不支持公开访问privateprotected成员,并不意味着底层框架不能提供对这些成员的访问。
这是那种情况之一,通常不应该使用反射等变通方法来访问或修改privateprotected成员,但框架仍然允许这样做。通常,您应该有一个非常好的理由来访问privateprotected成员;例如,实现需要查看对象内部状态以正确序列化对象的序列化器就是这样一个原因。如果您不是在做这样的事情,那么您应该真正考虑重新实现您正在操作的类,以便您不需要在程序中使用反射。

4

只有在代码运行在完全信任的情况下(或者具有相关权限)才允许这样做,否则会抛出MethodAccessException异常。

框架能够很好地适当限制访问 - 只有在您运行在完全信任或具有特定权限时才不这样做。请参见“反射的安全性考虑”获取更多详细信息。


2

这是框架提供的高级功能。在生产代码中调用方法时很少使用它,因为这会破坏成员隐藏的优势。

但有些情况下它可以派上用场:

  • 遗留代码测试 - 例如,假设您正在处理遗留代码并希望用单元测试覆盖它。如果您不允许更改代码并且想要测试部分功能,则调用私有方法是有用的。
  • 生产代码中的hack技巧 - 我曾经遇到过一个第三方控件的bug,在某些情况下私有清理未完成。使用私有调用,我可以解决这个问题。

框架提供这种功能没有问题,但在不必要的情况下使用它是错误的。


1

是的,它会违反规则。如果有人这样做,我几乎永远不会在审核期间通过代码。

使用反射调用方法非常缓慢,不安全,并且很容易在基础类重新编写私有方法时出错。

总之,我同意,这是一个坏主意!


1

反射是.NET中强大的功能,但也有其缺点。

优点:

  1. 反射允许访问所有成员(包括私有和受保护的成员),只要您至少具有ReflectionPermission安全性。(当您的应用程序从同一驱动器而不是从Internet访问反射的程序集时,可以获得此权限。)

  2. 在某些罕见情况下,反射是执行任务的唯一方法。

缺点:

  1. 反射破坏了安全性(与反编译程序集一样)。为了完全控制应用程序的代码和数据安全,您必须使用加密技术,而不能仅依赖于Private或Protected关键字,因为这些关键字单独使用很容易被反射或反编译破解。

  2. 反射比静态引用(通常调用方法的方式)慢得多且消耗更多资源。因此,除非这是解决问题的唯一方法,否则应避免使用反射。

以下是需要使用反射解决问题的示例

  1. 假设您的应用程序动态编译代码(例如,当您在运行时绘制用户提供的功能时),在这种情况下,加载程序集和类型的唯一方式是通过反射。

  2. 您想要克隆一个对象。您需要使用反射来访问其私有字段。

希望这能帮到您。 我应该在此感谢Francesco Balena先生的著作《Programming Microsoft Visual Basic 2005: The Language》。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接