为什么条件方法的返回类型必须为void?

时间:2017-09-26 11:59:35

标签: c# .net runtime clr language-design

我们正在为我们的API编写一些全局异常处理程序,我们只需要在Debug配置中执行某些方法,显然条件方法是可能的解决方案。

然而,我看到[Conditional("DEBUG")]只能用于返回类型为void的方法,如MSDN所说:

  

条件方法受以下限制:

     
      
  • 条件方法必须是类或结构中的方法   宣言。如果Conditional属性发生编译时错误   在接口声明中的方法上指定。
  •   
  • 条件方法的返回类型必须为void
  •   
  • 不能使用override修饰符标记条件方法。但是,条件方法可以用虚拟修饰符标记。这种方法的覆盖是隐式条件的,不能用条件属性明确标记。
  •   
  • 条件方法不能是接口方法的实现。否则,将发生编译时错误。
  •   

来源:https://msdn.microsoft.com/en-us/library/aa664622(v=vs.71).aspx

我们知道用ConditionalAttribute标记的方法到达IL,那么为什么CLR只是简单地拦截返回default(T)的方法调用,因此允许任何类型的返回类型的方法都是有条件的?或者我错过了什么?

1 个答案:

答案 0 :(得分:3)

  

为什么CLR不会简单地拦截返回default(T)

的方法调用

更重要的是......为什么应该发生?如果没有令人信服的理由这样做,那么没有令人信服的理由投入大量精力,工时,成本等来进行辩论,设计,考虑所有可能的情景,开发它,测试它,并继续在该语言的所有未来版本中支持它。对于首先不需要的功能而言,这是非常显着的节省。

保证void方法没有结果。因此,已经存在一个逻辑上的保证,即它的结果上没有依赖。返回值的方法不能提供这样的保证。

由于没有任何依赖于其结果,省略它并不会改变代码/逻辑的直接本地行为。如果某些 依赖于其结果(或者至少可能依赖于其结果),那么本地行为可能会发生变化,这是不可取的。这种情况可能会带来许多意想不到的变化。甚至像返回null一样简单,代码并不期望null

有人可能会亲自坚持认为,可以考虑自己的逻辑,并在编译器可以保证的范围之外做出自己的保证。 (类型转换和反射之类的东西对于开发人员来说可能是有用的工具,前提是他们可以保持他们认为可以的稳定性。)但在这种特殊情况下,非常快成为开发代码和生产代码不再做同样的事情。他们可能会做非常类似的事情,但不再是同样的事情。这是一个重大问题,语言试图避免这种情况。

这不是关于可以系统做什么。我确信在给定当时存在的信息的情况下,任何给定语言的任何给定版本都可以支持存在无穷无尽的各种事物。但应该吗?这完全是另一个问题。在这种情况下,支持这一点的成本似乎远远超过人们可能从中获得的成本。