使用 .NET 反射的私有方法。为什么?
我之前在公共方法上多次使用反射,但我从未意识到私有方法也可以被调用。请参阅私人成员的反思。
首先为什么允许这样做?这不是要打破“私人”就是“私人”的规则吗?
I used reflection many times before on public methods, but I never realized that private methods can be invoked too. See Reflection with private members.
Why is that allowed in the first place? Isn't that going to break the rule of "private" being "private"?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
C# 中的
private
实际上只是语言规范的一部分; C# 语言以及 Visual Basic 语言或任何其他合理的 .NET 语言(包括 CIL< /a>,所有 .NET 语言都编译成的),无法访问private
(或protected
,如果您不在派生类中)成员<强>用语言。但是,仅仅因为该语言不支持公开访问private
或protected
成员,并不意味着底层框架无法提供对那些成员。这是一种典型不应该使用反射等解决方法来访问或修改
私有
或受保护
成员的情况,但是框架无论如何都允许。一般来说,您应该有非常充分的理由来访问私有
或受保护
成员;例如,其中一个原因是实现一个序列化程序,该序列化程序需要查看对象的内部状态才能正确序列化该对象。如果您没有做类似的事情,那么您应该真正考虑重新实现您在内部探索的类,这样您就不需要在程序中使用反射。private
in C# is truly only part of the language specification; in the C# language, as well as in the Visual Basic language or any other sensible .NET language (including CIL, what all the .NET languages compile to) one is prevented from accessing aprivate
(orprotected
, if you're not within a derived class) member in the language. However, just because the language doesn't support publicly accessingprivate
orprotected
members doesn't mean the underlying framework can't provide access to those members.This is one of those cases where one typically shouldn't be using workarounds like reflection to access or modify
private
orprotected
members, but the framework allows one to anyway. Generally, you should have a very good reason to accessprivate
orprotected
members; one such reason, for example, is implementing a serializer that needs to look at the object's internal state to properly serialize the object. If you're not doing something like that, you should truly look at reimplementing the class you're poking around inside, so that you don't need to use reflection in your program.仅当代码在完全信任(或具有相关权限)下运行时才允许这样做。否则,将抛出
MethodAccessException
。该框架完全能够适当地限制访问 - 只是当您在完全信任下运行或具有特定权限时它不会这样做。有关何时使用的更多详细信息,请参阅“反射的安全注意事项”能够做到这一点。
This is only allowed when the code is running under full trust (or with the relevant permission). Otherwise, a
MethodAccessException
will be thrown.The framework is perfectly able to restrict access appropriately - it just doesn't do so when you're running under full trust or when you have specific permissions. See "Security Considerations for Reflection" for more details of when you're able to do this.
这是您从框架获得的高级功能。在生产代码中使用它来调用方法是非常不常见的,它破坏了成员隐藏的优点。
它在某些地方可能很有用:
框架提供此功能并没有什么问题,但在非必须的地方使用它就是错误的。
This is advanced power you get from the framework. It is very uncommon to use it in production code for invoking methods, it breaks the advantages of members hiding.
There are some places where it can be useful:
There is nothing wrong with the framework providing this functionality, but using it where it's not a must is wrong.
是的,它确实违反了规则。如果有人这样做,我几乎永远不会在审查期间通过代码。
使用反射来调用方法是非常糟糕的,不是类型安全的,并且如果底层类对私有方法进行了修改,则很容易中断。
简而言之,我同意,这是一个坏主意!
Yep, it does break the rule. I'd almost never pass code during a review if someone did this.
Using reflection to call a method is slllloooow, not type-safe, and breaks easily if the underlying class has the private methods reworked.
So in short, I agree, it's a bad idea!
反射是 .NET 中的一项强大功能,但也有其缺点。
优点:
反射允许访问所有成员(包括私有成员和受保护成员),前提是您至少具有 ReflectionPermission 安全性。 (当您的应用程序从同一驱动器而不是从 Internet 访问反射程序集时,可以获得此权限。)
在某些极少数情况下,反射是执行任务的唯一方法。
缺点:
反射会破坏安全性(反编译程序集也会破坏安全性)。为了获得应用程序代码和数据的完全安全性,您必须使用加密技术,而不仅仅是依赖 Private 或 Protected 关键字,因为如果单独使用,很容易通过反射或反编译来破坏。
反射比静态引用(调用方法的正常方式)慢得多并且消耗更多资源。因此,您应该避免反射,除非这是解决问题的唯一方法。
反射是解决问题的唯一方法的示例如下:
假设您的应用程序动态编译代码(例如,当您绘制用户在运行时提供的函数时)。在这种情况下,加载程序集和类型的唯一方法是通过反射。
您想要克隆一个对象。您需要使用反射来访问其私有字段。
我希望这有帮助。
在此我要感谢 Francesco Balena 先生的精彩著作《Microsoft Visual Basic 2005 编程:语言》。
Reflection is a powerful functionality in .NET but has also its cons.
Pros:
Reflection permits accessing all members (including the private and protected), provided that you have at least the ReflectionPermission security. (This permission can be gained when your application accesses the reflected assembly from the same drive, not from the Internet.)
In some rare cases, reflection is the only way to perform a task.
Cons:
Reflection breaks security (as does decompiling an assembly). To gain complete security over your application's code and data, you must use cryptography, not just rely on the Private or Protected keywords because, if alone, can be easily broken through reflection or decompilation.
Reflection is much slower and consumes more resources than static referencing (the normal way you call methods). For this reason, you should avoid reflection unless this is the only way to solve your problem.
Examples of when reflection is the only way to solve the problem follow:
Suppose your application dynamically compiles code (such as when you're plotting functions that the user provide at run-time). In such cases, the only way to load the assemblies and types is through reflection.
You want to clone an object. You'd need to use reflection to access its private fields.
I hope this helps.
I should thank here Mr. Francesco Balena for his beautiful book, Programming Microsoft Visual Basic 2005: The Language.