修复';使用未分配的局部变量';带有null赋值.为什么?

本文关键字:null 带有 赋值 局部变量 为什么 分配 修复 | 更新日期: 2023-09-27 17:58:09

使用这样的代码,编译器会在c.MyProperty:上抱怨

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

然而,如果您在初始化时将null分配给c,它不会抱怨:

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

那么,为什么这样做呢?如果c没有被分配一个null,并且编译器假设允许它,那么c.MyProperty不是也会抛出同样的异常吗?对象引用没有设置为对象的实例

修复';使用未分配的局部变量';带有null赋值.为什么?

当您将null分配给变量时,您是在告诉编译器后退,因为您比他更了解,所以他不应该抱怨这一点。

这可能是因为分配null被认为意味着开发人员的显式操作。

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

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

[跳过]

C#要求局部变量必须明确赋值才能获得其值。

正如Binary Worrier巧妙地指出的那样,这是为了避免让你朝自己的脚开枪。

这样想吧,编译器并不是告诉你它将抛出一个null引用,因此它无法编译,而是告诉你它不满足编译所需的条件之一,即必须明确地分配它。

根据规范,null是一个c#文字:"null文字可以隐式转换为引用类型或可为null的类型"

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

从规范开始报价

5.3.3确定明确分配的精确规则为了确定每个使用的变量都被明确分配,编译器必须使用与本节中描述的过程等效的过程。

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

·在每个语句的开头

·在每个报表的终点(§8.1)

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

·在每个表达式的开头

·在每个表达式的末尾

报价结束

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

出现此异常的原因是您没有为变量分配默认值,例如

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

现在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);