以前我在公共方法上多次使用过反射,但我从未意识到私有方法也可以被调用。请参见Reflection with private members。
为什么会允许这样做呢?这不会违反“私有”就意味着“私有”的规则吗?
以前我在公共方法上多次使用过反射,但我从未意识到私有方法也可以被调用。请参见Reflection with private members。
为什么会允许这样做呢?这不会违反“私有”就意味着“私有”的规则吗?
private
实际上只是语言规范的一部分;在C#语言以及Visual Basic语言或任何其他合理的.NET语言(包括所有.NET语言编译成的CIL)中,通过语言是无法访问private
(或protected
,如果您不在派生类中)成员的。然而,仅仅因为语言不支持公开访问private
或protected
成员,并不意味着底层框架不能提供对这些成员的访问。private
或protected
成员,但框架仍然允许这样做。通常,您应该有一个非常好的理由来访问private
或protected
成员;例如,实现需要查看对象内部状态以正确序列化对象的序列化器就是这样一个原因。如果您不是在做这样的事情,那么您应该真正考虑重新实现您正在操作的类,以便您不需要在程序中使用反射。只有在代码运行在完全信任的情况下(或者具有相关权限)才允许这样做,否则会抛出MethodAccessException
异常。
框架能够很好地适当限制访问 - 只有在您运行在完全信任或具有特定权限时才不这样做。请参见“反射的安全性考虑”获取更多详细信息。
这是框架提供的高级功能。在生产代码中调用方法时很少使用它,因为这会破坏成员隐藏的优势。
但有些情况下它可以派上用场:
框架提供这种功能没有问题,但在不必要的情况下使用它是错误的。
是的,它会违反规则。如果有人这样做,我几乎永远不会在审核期间通过代码。
使用反射调用方法非常缓慢,不安全,并且很容易在基础类重新编写私有方法时出错。
总之,我同意,这是一个坏主意!
反射是.NET中强大的功能,但也有其缺点。
优点:
反射允许访问所有成员(包括私有和受保护的成员),只要您至少具有ReflectionPermission安全性。(当您的应用程序从同一驱动器而不是从Internet访问反射的程序集时,可以获得此权限。)
在某些罕见情况下,反射是执行任务的唯一方法。
缺点:
反射破坏了安全性(与反编译程序集一样)。为了完全控制应用程序的代码和数据安全,您必须使用加密技术,而不能仅依赖于Private或Protected关键字,因为这些关键字单独使用很容易被反射或反编译破解。
反射比静态引用(通常调用方法的方式)慢得多且消耗更多资源。因此,除非这是解决问题的唯一方法,否则应避免使用反射。
以下是需要使用反射解决问题的示例:
假设您的应用程序动态编译代码(例如,当您在运行时绘制用户提供的功能时),在这种情况下,加载程序集和类型的唯一方式是通过反射。
您想要克隆一个对象。您需要使用反射来访问其私有字段。
希望这能帮到您。 我应该在此感谢Francesco Balena先生的著作《Programming Microsoft Visual Basic 2005: The Language》。