将变量赋值为null的是什么?

时间:2012-03-15 17:52:28

标签: c#

在下面我得到一个编译时错误,上面写着“使用未分配的局部变量'匹配'” 如果我只输入字符串匹配;但是当我使用string match = null时它可以工作; 那么区别是什么呢?一般来说,如果没有立即为字符串赋值,我应该像这样分配给null吗?

string question = "Why do I need to assign to null";
char[] delim = { ' ' };
string[] strArr = question.Split(delim);
//Throws Error
string match;
//No Error
//string match = null;
foreach (string s in strArr)
 {
    if (s == "Why")
      {
         match = "Why";
      }
 }
Console.WriteLine(match);

6 个答案:

答案 0 :(得分:12)

C#语言在明确赋值之前阻止使用本地语言。在此示例中,编译器不理解Split的语义,并且必须假设strArr可以是空集合,因此循环体可能无法执行。这意味着从明确的分配角度来看,foreach不会为match分配值。因此,当您到达WriteLine

时,它仍然未分配

通过将声明更改为string match = null,该值从一开始就标记为明确分配。因此循环计算无关紧要

答案 1 :(得分:5)

取决于您的方案:

string match = null;

或者:

string match = string.Empty;

都是可接受的做法。

在您的情况下,match永远不会分配值,因此编译错误。

答案 2 :(得分:4)

您正在寻找声明和作业之间的区别。声明,如

string match;

只需声明到编译器,您将使用类型为string的变量match。分配,用

这样的行
match = null;

将值null分配给match

语言可能声明声明和赋值必须始终分开(我不是100%肯定,但我相信旧版本的Visual Basic可以做到这一点),但大多数语言允许你结合声明和作业,写作

string match = null; // combined declaration and assignment

表示

string match; // declaration
match = null; // assignment

C#要求在使用变量之前分配变量。与字段和事件不同,局部变量不会自动分配默认值,因此您必须向编译器证明,在使用match之前,match将具有一些值。编译器不关心match具有哪个值,只要该变量的类型为string。

在您的情况下,编译器无法通过本地分析证明strArr将是非空的,因为编译器不检查Split的代码,因此无法保证代码将即使进入foreach循环,也要符合条件以分配给match。由于Console.WriteLine调用使用match,并且由于match可能未在运行时使用string match声明分配,因此编译器要求您在match之外指定string match = null环。满足要求的一种方法是使用string match代替{{1}}。

答案 3 :(得分:2)

编译器已经意识到,如果没有将match分配给任何东西,你有可能使用foreach。 {{1}}循环可能永远不会被执行。所以你已经声明了变量,但是编译器已经意识到它可以在没有被分配的情况下被访问,因此错误。

答案 4 :(得分:1)

如果符合条件,那里会有if()块,它会初始化变量'match'。在这种情况下,match是表示内存中实际块的对象。

但是,如果不满足if()条件,则没有'else'块执行'match'变量的默认初始化,在这种情况下,您将尝试访问未初始化的对象,这会失败。

您可以通过以下方式解决此问题:

  1. 正如您所评论的那样,默认在for循环之前初始化'match'。
  2. 在for循环后添加默认的“else”条件。
  3. 幸运的是,如果您正在使用IDE,它会将此作为编译异常指出。

答案 5 :(得分:0)

当您声明type variable = null;时,您正在初始化变量。如果您声明type variable;,那么您只是声明变量。