Reflection 反射:仅用于框架?

Reflection 反射:仅用于框架?,reflection,metaprogramming,Reflection,Metaprogramming,我的同事和尊敬的人曾经对我说,不应该在应用程序代码中使用反射,而应该只在框架中使用反射。他是在J2EE背景下发言的,我在该平台上的专业经验通常证明了这一点;尽管我曾经用Java编写过一两次反射式应用程序代码 我对RubyonRails的体验完全不同,因为Ruby非常鼓励您编写动态代码。如果没有反射和元编程,Rails提供的许多功能都是不可能实现的,而且许多相同的技术对应用程序代码同样适用和有用 您是否同意反射仅用于框架的观点?我很想听听你的意见和经验 我不同意,我的应用程序使用反射来动态创建提

我的同事和尊敬的人曾经对我说,不应该在应用程序代码中使用反射,而应该只在框架中使用反射。他是在J2EE背景下发言的,我在该平台上的专业经验通常证明了这一点;尽管我曾经用Java编写过一两次反射式应用程序代码

我对RubyonRails的体验完全不同,因为Ruby非常鼓励您编写动态代码。如果没有反射和元编程,Rails提供的许多功能都是不可能实现的,而且许多相同的技术对应用程序代码同样适用和有用

  • 您是否同意反射仅用于框架的观点?我很想听听你的意见和经验

    • 我不同意,我的应用程序使用反射来动态创建提供者。如果逻辑很简单并且不需要更复杂的模式,我也可以使用反射来控制逻辑流


      在C#中,我使用反射从枚举中获取属性,帮助我确定如何向最终用户显示枚举。

      我不同意,反射在应用程序代码中非常有用,我发现自己经常使用它。最近,我不得不使用反射从程序集的路径加载程序集(以便调查其公共类型)

      这里就这个问题发表了几点看法


      在没有其他方法时使用反射!这是一个性能问题

      如果您以前研究过.NET性能缺陷,那么正常反射的速度可能不会让您感到惊讶:重复访问int属性的简单测试证明使用反射比直接访问属性慢约1000倍(比较测量时间中位数80%的平均值)

      见此:


      MSDN有一篇关于

      的非常好的文章,如果您的问题最好通过使用反射来解决,那么您应该使用它

      (请注意,“最佳”的定义是从经验中学到的:)


      框架与应用程序的定义也不是那么简单。有时你的应用程序需要一点框架来做好它的工作。

      有一个老笑话,任何用静态类型语言编写的足够复杂的系统都包含一个不完整的、低劣的Lisp实现

      由于随着项目的发展,您的需求往往会变得更加复杂,因此您经常最终会发现静态类型对象系统中的常见习惯用法最终会碰壁。有时候,寻求反思是最好的解决办法

      我对Ruby等动态类型语言和C#等静态类型语言很满意,但Ruby中的隐式反射通常使代码更简单、更易于阅读。(取决于所需的元编程魔法,有时更难编写)


      在C#中,我发现了一些不经过思考就无法解决的问题,因为我在运行时才获得信息。举个例子:当试图操作生成另一个进程中运行的Silverlight对象代理的第三方代码时,我必须使用反射来调用方法的特定强类型“泛型”版本,因为编组需要调用方对另一个进程中的对象类型进行假设,以便从中提取我们需要的数据,而C#不允许在运行时指定泛型方法调用的“类型”(反射技术除外)。我想你可能会说我们的工具是一种框架,但我可以很容易地想象一个普通应用程序面临类似问题的情况。

      反射使DRY变得更容易。毫无疑问,编写没有反射的枯燥代码是可能的,但它通常要冗长得多

      如果某些信息以某种方式编码在我的程序中,如果这是最简单的方式,为什么我不使用反射来获取它呢


      听起来他是专门谈论Java的。在这种情况下,他只是引用了一个特殊的例子:在Java中,反射非常不稳定,几乎从来都不是最简单的方法。:-)正如您所看到的,在Ruby等其他语言中,反射经常被使用。

      反射肯定在框架中大量使用,但如果使用正确,可以帮助简化应用程序中的代码

      我以前见过的一个例子是使用大型接口(20多个方法)的JDK代理来包装(即委托给)特定的实现。只有几个方法使用InvocationHandler被重写,其余的方法通过反射被调用


      反射可能很有用,但执行常规方法调用要慢一些。见此。

      Java中的反射通常是不必要的。这可能是解决某个问题的最快方法,但我更愿意解决导致您认为它在应用程序代码中是必要的潜在问题。我之所以相信这一点,是因为它经常将错误从编译时推到运行时,这对于足够大的软件来说总是一件坏事,因为测试是不平凡的。

      我认为,在应用程序代码中不应该使用反射,它应该只在框架中使用,这或多或少是正确的

      从某些代码的耦合程度来看,通过反射连接起来的代码是松散耦合的


      因此,通过反射完成其工作的代码可以非常愉快地履行其在生活中的角色,而对使用它的代码一无所知。

      这将是格林斯潘的第十条规则“任何足够复杂的C或Fortran程序都包含一个特殊的、非正式指定的、充满bug的、缓慢的通用Lisp的一半的实现”我知道事情是这样的:)