23

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

var thingy = new Foo();

但为什么不...

var getFoo() {
    return new Foo(); 
}
4

6 回答 6

43

Eric Lippert 写了一篇关于这个主题的完整博客文章。

总之,主要问题是需要对 C# 编译器进行重大的重新架构才能做到这一点。目前以单程方式处理声明。这将需要多次传递,因为能够在推断变量之间形成循环。VB.NET 也有大致相同的问题。

于 2009-05-05T13:01:21.993 回答
7

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

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

为什么不?

var getFoo() {
    return new Foo(); 
}

这样做的原因是:

如果什么?

class Foo {}

var GetFoo() {
   return GetBar(); 
}

var GetBar() {
  return GetBaz(); 
}

var GetBaz() {
   return new Foo();
}

您可以推断出GetFoo将要返回Foo,但您必须跟踪该方法及其子项所做的所有调用,以推断类型。就目前而言,C# 编译器并非旨在以这种方式工作。在推断类型的代码可以运行之前,它需要在流程的早期使用方法和字段类型。

在纯粹的美学层面上,我发现方法上的 var 定义混淆了事物。它是我认为明确总是有帮助的一个地方,它通过意外返回导致您的签名和大量其他相关方法签名更改的类型来保护您免于自责。更糟糕的是,如果您返回返回对象的方法的值并且碰巧很幸运,您甚至可能在不知道自己这样做的情况下更改了方法链的所有签名。

我认为 var 方法最好留给像 Ruby 这样的动态语言

于 2009-05-05T14:30:35.370 回答
1

因为它更容易做到。如果您要推断所有类型,则需要像 Hindley Milner 类型推断系统这样的东西,它将把您钟爱的 C# 变成 Haskel 派生语言。

于 2009-05-05T13:04:17.713 回答
1

从本质上讲,您遇到的问题是 C#(到目前为止)是一种静态类型的语言。定义为 var 的局部变量仍然是静态类型的,但在语法上是隐藏的。另一方面,返回 var 的方法有很多含义。它更像是一个使用接口,使用 var 并没有任何收获。

于 2009-05-05T13:23:15.263 回答
1

您可以在 vs 2010 Dynamic中使用

Dynamic getFoo() { 
    return new Foo();  
} 
于 2010-05-05T11:41:23.660 回答
0

我认为这是因为隐含类型的范围更广,因此比单一方法的范围更容易引起问题。

于 2009-05-05T13:02:01.570 回答