使用空赋值修复“使用未分配的局部变量”。 为什么?

使用这样的一段代码,编译器在c.MyPropertyc.MyProperty

 MyClass c; try { throw new Exception(); } catch (Exception) { } c.MyProperty = 2; // "Use of unassigned local variable 'c'". 

但是,如果在初始化中为c分配null ,则不会抱怨:

 MyClass c = null; try { throw new Exception(); } catch (Exception) { } c.MyProperty = 2; // no complains this time. 

那么,为什么这有效呢? 如果c没有赋值为null并且编译器假设允许它,那么不会在c.MyProperty抛出相同的exception, 对象引用没有设置为对象的实例吗?

当你给变量赋值null时,你告诉编译器退出,因为你比他更了解所以他不应该抱怨这个。

这可能是由于分配null被认为暗示开发人员的明确行为。

可以这样想,编译器并没有告诉你它会抛出一个空引用,因此无法编译,而是编译所需的条件之一,即它具有明确分配。

根据规范,null是ac#literal:“null-literal可以隐式转换为引用类型或可空类型”

在任务方面:(取自规范)

从规范中开始引用

5.3.3确定明确赋值的精确规则为了确定每个使用的变量是明确赋值的,编译器必须使用与本节中描述的相同的过程。

编译器处理每个函数成员的主体,该成员具有一个或多个最初未分配的变量。 对于每个最初未分配的变量v,编译器在函数成员中的以下每个点确定v的明确赋值状态:

·在每个陈述的开头

·在每个陈述的终点(§8.1)

·在每个弧上将控制转移到另一个语句或语句的结束点

·每个表达式的开头

·每个表达式的结尾

报价结束

因此,即使null实际上没有指向内存中的对象,它确实满足了明确赋值的要求,这就是编译器允许它的原因。

这是因为C#语言规范v.4.0第1.6.6.2节“方法主体和局部变量”声明如下:

方法体可以声明特定于方法调用的变量。 这些变量称为局部变量。

[跳过]

C#需要在可以获得其值之前明确赋值

这是为了避免让你自己在脚下射击,正如Binary Worrier巧妙地指出的那样。

此exception的原因是您没有为变量分配默认值,例如

 if (Request.Files != null && Request.Files.Count > 0) { Image = Request.Files.AllKeys[0]; } var stream = new FileStream(Image,FileMode.Open); 

现在Image变量会给编译器错误

使用未分配的局部变量’Image’

这是因为有可能条件变为真,控制永远不会知道Image变量是什么。 所以要么放置一个else块,要么指定一个默认值,如下所示。

 string Image = ""; if (Request.Files != null && Request.Files.Count > 0) { Image = Request.Files.AllKeys[0]; } var stream = new FileStream(Image,FileMode.Open);