隐式打字; 为什么只是局部变量?

Ed *_*ess 22 .net c# variables implicit-typing

有没有人知道或关心为什么隐式类型仅限于局部变量?

var thingy = new Foo();
Run Code Online (Sandbox Code Playgroud)

但为什么不......

var getFoo() {
    return new Foo(); 
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 42

Eric Lippert做了一篇关于这个主题的整篇博文.

总之,主要问题是它需要C#编译器的主要重新架构才能这样做.声明目前以单程方式处理.这将需要多次通过,因为能够在推断的变量之间形成循环.VB.net有大致相同的问题.

  • 对于字段定义,类型推断的非常受限制的版本将走99%(IMHO)...仅支持var dict = new Dictionary <int,int>(); 不支持通过方法初始化的var字段. (7认同)
  • 我知道有办法做到这一点.我们现在选择不做任何一件事; 他们的成本不值得. (5认同)

Sam*_*ron 7

Jared在他的回答中有一个很棒的链接,一个很棒的话题.

我认为它没有明确地回答这个问题.

为什么不?

var getFoo() {
    return new Foo(); 
}
Run Code Online (Sandbox Code Playgroud)

原因是:

如果?

class Foo {}

var GetFoo() {
   return GetBar(); 
}

var GetBar() {
  return GetBaz(); 
}

var GetBaz() {
   return new Foo();
}
Run Code Online (Sandbox Code Playgroud)

您可以推断出GetFoo将要返回的内容Foo,但是您必须跟踪方法所做的所有调用以及它的子项只是为了推断类型.目前,C#编译器不是以这种方式工作的.在推断类型可以运行的代码之前,它需要在过程的早期阶段使用方法和字段类型.

在纯粹的美学层面上,我发现方法上的var定义会混淆事物.它是我认为明确的一个地方总是有帮助的,它可以保护你不会因为意外地返回导致你签名的类型以及大量其他依赖方法签名而在脚中射击自己.最糟糕的是,如果你返回一个返回对象并且碰巧幸运的方法的值,你甚至可能会改变你所有的方法链签名而不知道你这样做了.

我认为var方法最适合像Ruby这样的动态语言

  • 不,那不是问题.我们已经在C#中解决了这个问题,正如您可以证明的那样.如果将getFoo变为lambda,我们将推断lambda的返回类型为Foo.但是存在真正的问题.一个问题是,如果"var getFoo(){...}"调用"var getBar(){...}",而这反过来调用......你最终必须进行整个程序分析才能输入方法.当前的编译器体系结构假定在分析方法体之前可以键入方法和字段. (12认同)