为什么C#未赋值的本地变量不默认为null?

11

假设我有这样的东西:

public IOrder SomeMethodOnAnOrderClass()
{
   IOrder myOrder = null;

   if (SomeOtherOrder != null)
   {
       myOrder = SomeOtherOrder.MethodThatCreatesACopy();        
   }

   return myOrder;
}

为什么C#的制作者要求明确将myOrder设置为null
在哪些情况下你会想要让它保持未赋值状态?
将其设置为null是否有成本?即使变量后来会被设置为其他值,您也不希望总是将未分配的变量设置为null吗?
或者这是必须的,以确保你已经“条理清晰,步步到位”?
还是有其他原因?

2
因为某些类型是不可为空的,例如结构体。默认值等于 default(IOrder) - Austin Brunkhorst
相关问题:https://dev59.com/_G025IYBdhLWcg3wHR4Y - Despertar
2
请参阅http://blogs.msdn.com/b/ericlippert/archive/2012/03/05/why-are-local-variables-definitely-assigned-in-unreachable-statements.aspx。 - MiMo
@KonstantinVasilcov - 这似乎并没有提到“为什么”。只是更多的关于“什么”和“如何”。(当然,我可能没有理解Eric。有时我很难完全理解他的帖子。) - Vaccano
显示剩余3条评论
2个回答

11

它们默认为null或更准确地说,您的对象默认为default(T)返回的值,对于值类型而言,这个值是不同的。

这是一种特性。在野外有各种各样由程序员使用未初始化变量引起的错误。并非所有语言都能为此类问题提供如此明确定义的行为(你知道你是谁...)。

显然,您尚未经历过这种情况。感到高兴,并接受编译器帮助您编写更好的代码。


1
足够正确,但我认为问题更多地涉及编译器为什么阻止您使用未明确初始化的本地变量。 - RJ Lohan
正如我的例子所示,我指的是局部变量。抱歉,我应该表达得更清楚些。 - Vaccano
我有点想知道为什么你描述的情况对于局部变量不会发生。 - Vaccano
@Vaccano:我的回答是关于局部变量的。原因是一样的。初始化变量是一个好习惯。代码可能会随着时间的推移而改变,如果你在声明和另一段代码之间添加了一些代码,这段代码假定在使用变量之前可能未初始化该变量(但新代码不需要),那么你可能会有一个错误。C和C++允许这样做(虽然你会得到一个警告),未初始化变量的值是不确定的(读取未初始化变量会导致UB)。你可以想象这如何导致错误。 - Ed S.

8
为什么在不可达语句中局部变量被绝对分配(感谢MiMo提供链接)一文中,Eric Lippert说道:
引用:

我们想要将其视为非法的原因不是因为局部变量将被初始化为垃圾,我们想要保护您免受垃圾的影响。我们事实上会自动将局部变量初始化为它们的默认值。(尽管C和C++编程语言不会这样做,并且会欣然允许您从未初始化的局部变量中读取垃圾。)相反,这是因为这样的代码路径可能是一个错误,我们希望将您投入到质量的深渊中;您应该努力工作才能避免写出这种错误。

根据我对此的理解,如果一个局部变量没有被赋值,这并不意味着开发人员确实希望在读取它时获得default(T)。这在大多数情况下意味着开发人员可能错过了它并忘记初始化它。这更像是一个错误,而不是一个开发人员有意通过声明来将局部变量初始化为default(T)的情况。

3
@Vaccano:没错,从未初始化的本地变量中读取数据几乎肯定是一个错误,因此编译器会提示你而不是忽略它。 - Eric Lippert
@Vaccano,本地变量也会获得默认值,但是如果本地变量没有明确赋值,则会生成编译时错误。为什么类字段不会生成相同的错误,请尝试亲自询问Eric。感谢他的评论,让您有了这个机会)) - horgh
@EricLippert - 那么,为什么局部变量会被分配默认值呢?(如果它永远不会被使用。)而类级别的字段为什么没有得到同样的处理呢?(我认为这太复杂了,编译器无法捕捉,但我还是想问一下。) - Vaccano
3
@Vaccano:请参见https://dev59.com/yWYq5IYBdhLWcg3whQ40#14419363。 - Eric Lippert
@groverboy 这不是一个警告,而是一个错误。Vaccano问,如果局部变量实际上从未被读取,那么为什么要将默认值分配给它,因为它肯定会被至少最后的确定赋值覆盖。 - horgh
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接