microsoft决定禁用类型推断的原因与';在vb.net中不能在静态上工作?

microsoft决定禁用类型推断的原因与';在vb.net中不能在静态上工作?,vb.net,Vb.net,这个问题应该与另一个问题略有不同 类型推断不适用于静态变量 Static lastAccessed = Now.AddDays(-1) Function DoSomething(value As Integer) As Integer Dim foo As IFoo = New FirstFooImplementation() foo.DoProcess() Dim result1 As Integer = foo.EndResult foo = New Sec

这个问题应该与另一个问题略有不同

类型推断不适用于静态变量

Static lastAccessed = Now.AddDays(-1)
Function DoSomething(value As Integer) As Integer
    Dim foo As IFoo = New FirstFooImplementation()
    foo.DoProcess()
    Dim result1 As Integer = foo.EndResult
    foo = New SecondFooImplementation()
    foo.DoProcess()
    Dim result2 As Integer = foo.EndResult
    Return result1 + result2
End Function
简单的代码

LastAccess类型应为日期

塔达,这是目标

为什么?

显然,
Dim lastAccessed=Now.AddDays(-1)
可以正常工作

为什么?

注意:我很清楚我没有使用as子句。我故意不这么做,因为这就是类型推断的目的。编译器可以清楚地看到,即使没有as子句,变量的类型也必须是Date

我也知道这可能只是设计决策。然而,我想知道微软为什么做出这样的决定?显然,静态变量可以像任何局部变量一样推断出来

所以问题是,无论我们使用dim还是static,我们都知道编译器可以在编译时推断类型

那么为什么微软决定不允许对静态变量进行推断呢

这个问题几乎没有触及问题。问题中甚至不清楚提问者是否使用静态变量,因为他使用dim。但答案仍然没有说明为什么设计是这样的。 来自 (我的重点):

类型推断只能用于非静态局部变量;它不能用于确定类字段、属性或函数的类型

类似地,局部类型推断不适用于声明为静态的过程级变量

似乎是微软的设计决定。 我猜他们认为在这种典型的习惯用法中,局部变量是初始化的,并且从不重新赋值,这样做的好处是最大的

Function DoSomething(value As Integer) As Integer
    Dim foo = New Foo(value)
    foo.DoProcess()
    Return foo.EndResult
End Function
(尽管有人可能会说这个函数违反了依赖倒置原则。)

至于静态变量,这些变量通常更容易成为“有状态”变量, 因此,总是显式地指定其类型是有意义的。显然,当初始值设定项和后续赋值共享同一类型(例如整数)时没有问题。当静态变量可以分配给同一接口的不同实现时,情况就不同了

Function DoSomething(value As Integer) As Integer
    Static foo As IFoo = New DefaultFooImplementation()
    If value <> 0 Then   ' else stick to the previous foo
        foo = FooFactory.Create(value)
    End If
    foo.DoProcess()
    Return foo.EndResult
End Function
但老实说,重用这样的变量应该被认为是不好的做法。我可以想象微软拒绝刺激这一点

我承认,本地人和静态人之间不是黑白分明的。
仍然要由开发人员来判断类型推断是否适用于任何给定的情况。

Eric Lippert在11年前的一篇博文中谈到了为什么C#编译器不能使用这种方法:

在模块级别(从功能上来说,
静态
变量)进行类型推断比看起来要微妙得多。试图在模块级别推断类型可能会带来一系列麻烦(包括无法解决的循环的可能性)。虽然对于最简单的情况来说这确实不是问题,但是编译器开发人员需要担心复杂的情况


我假设C#的推理也适用于VB。

似乎对我说
静态变量不算作局部变量。这回答了你的问题吗?你们有严格的选择吗?除了阻止代码编译之外,它没有任何帮助。存在类型推断是为了支持在LINQ中使用匿名类型。它得到了更广泛的应用,但这就是它存在的原因。我想,除了非静态局部变量之外,类型推断是不受支持的,因为匿名类型在这些上下文中不受支持。我隐约记得Eric Lippert在C#的上下文中讨论过同样的问题,它与编译器在传递模块上下文时可以获得哪些信息有关。如果您能解释得更多,我将非常高兴。看来你的答案是正确的。然而,你能解释为什么静态变量也应该有显式类型,因为我们可以在编译时很容易地推断出类型吗?@user4951我编辑了我的答案,添加了一个示例。但我想Eric Lippert的文章更能说明问题。谢谢你的链接!我将注意到,实际上有两个地方可以避免重复:在声明中(通过var)或在构造函数中(通过target-typed
new
)。后者没有埃里克描述的问题。有关此提案的当前状态,请参阅。target-typed
new
的缺点是它不能用于避免工厂调用中的显式声明等…但是在构造函数的特定情况下,消除重复的价值要高得多。