在下面我得到一个编译时错误,上面写着“使用未分配的局部变量'匹配'” 如果我只输入字符串匹配;但是当我使用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);
答案 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'变量的默认初始化,在这种情况下,您将尝试访问未初始化的对象,这会失败。
您可以通过以下方式解决此问题:
幸运的是,如果您正在使用IDE,它会将此作为编译异常指出。
答案 5 :(得分:0)
当您声明type variable = null;
时,您正在初始化变量。如果您声明type variable;
,那么您只是声明变量。