我已经注意到在处理表达式或表达式树时,我经常使用反射来设置和获取属性以及您所拥有的值。在我看来,反射的使用似乎越来越普遍。诸如用于验证的数据注释,属性繁重的ORM等之类的东西。我想知道:自从几年前和几年前我被告知尽可能避免反思以来,发生了什么变化?
那如果发生了什么变化呢?仅仅是机器的速度吗?是否对框架进行了更改以加快反思?
还是什么都没有真正改变?使用反射还是“不好”还是“慢”?
我已经注意到在处理表达式或表达式树时,我经常使用反射来设置和获取属性以及您所拥有的值。在我看来,反射的使用似乎越来越普遍。诸如用于验证的数据注释,属性繁重的ORM等之类的东西。我想知道:自从几年前和几年前我被告知尽可能避免反思以来,发生了什么变化?
那如果发生了什么变化呢?仅仅是机器的速度吗?是否对框架进行了更改以加快反思?
还是什么都没有真正改变?使用反射还是“不好”还是“慢”?
Answers:
反思既不坏也不慢。它只是一个工具。像所有工具一样,它在某些情况下非常有价值,而在其他情况下则不那么有价值。
如果确实存在性能问题,则可以始终使用FasterFlect之类的库。
进一步阅读
如果反射效率低下,什么时候最合适?
dynamic
-显然比反射快一个数量级。
人们警惕不必要使用反射的原因不是性能:是的,使用反射会产生一些开销,但是通常情况下,解决反射问题需要使用具有相当复杂性的另一种方法,即使没有,开销也是很少有意义(尤其是对于应用程序级开发)。
使用反射,人们通常可以对源代码做出的一些重要假设被打破,并且诸如“查找所有引用”之类的工具不再可靠地工作。反射基本上还消除了编译器在C#中强制执行的大多数类型安全,以及类型系统通常会捕获并转化为编译器错误的大多数编程错误,现在最多变为运行时错误,或者变为最模糊的错误。
那么为什么人们要使用反射呢?简而言之,因为尽管存在上述问题,它还是一个非常有价值的工具。通过反思,可以在像C#这样的静态,严格类型化的语言中获得动态编程的一些好处,并且动态编程语言最近已经显示出它们的优点,尤其是在Web编程领域-PHP,Javascript和相当著名的Python ,所有都使用动态类型输入,并被证明非常适合Web编程。但是由于该语言仍然是C#,因此您可以选择将大多数应用程序保留在严格类型的OOP惯用语中,并编写其中动态行为确实对反射有所帮助的一小部分。
一个典型的例子是当您需要将方法公开为Web服务调用时(使用.NET中尚未内置的协议)。严格类型化的OOP方法确实有效,但是它过于严格且笨拙。但是,如果您使用反射将对方法的调用映射而将键/值对映射为参数,则可以为此类Web服务编写一次管道,然后在您喜欢的任何类上使用它。
反射仍然比直接调用慢得多。发生了两件事:
综上所述,这两个因素使反射的成本降低到了您可以常规使用它的程度(在适当的情况下可从可维护性POV中使用),并等待探查器告诉您它是否实际上是瓶颈(并合理地确保大多数时间不会过去)。