C# 循环中的变量声明不';无法重置为默认值
考虑以下代码:C# 循环中的变量声明不';无法重置为默认值,c#,loops,compiler-construction,declaration,C#,Loops,Compiler Construction,Declaration,考虑以下代码: for (int i = 0; i < 10; i++) { bool b; /* #1 */ if (i == 0) { b = true; /* #2 */ } } for(int i=0;i
for (int i = 0; i < 10; i++)
{
bool b; /* #1 */
if (i == 0)
{
b = true; /* #2 */
}
}
for(int i=0;i<10;i++)
{
布尔b;/*#1*/
如果(i==0)
{
b=真;/*#2*/
}
}
我在#1和#2设置了断点
第一次(i=0),b在#1设置为false,而在#2设置为true
第二次(i=1),b在#1时为真
这对我来说没有意义,因为我假设在第二个循环(I=1)中开始时,b在声明时应该再次为false
我假设在第二个循环中的#1处b=false。
有人想解释一下吗?您在调试器中看到的
b
的值无效。C#要求在读取所有局部变量之前,必须对其进行初始化或赋值。因此,您在VisualStudio中的调试器中看到的值是无用的,因为它无法读取。无法编写在第二次迭代时“看到”该值被设置为true
的C#代码,因为编译器会将此类使用标记为无效:
for (int i = 0; i < 10; i++)
{
bool b; /* #1 */
Console.WriteLine(b); // <<== INVALID!!! This will not compile.
// error CS0165: Use of unassigned local variable `b'
if (i == 0)
{
b = true; /* #2 */
}
}
for(int i=0;i<10;i++)
{
布尔b;/*#1*/
Console.WriteLine(b);//在调试器中看到的b
的值无效。C#要求初始化或分配所有局部变量,然后才能从中读取。因此,在Visual Studio中的调试器中看到的值是无用的,因为它无法读取。无法编写一段“看到”在第二次迭代中将该值设置为true
,因为编译器会将此类使用标记为无效:
for (int i = 0; i < 10; i++)
{
bool b; /* #1 */
Console.WriteLine(b); // <<== INVALID!!! This will not compile.
// error CS0165: Use of unassigned local variable `b'
if (i == 0)
{
b = true; /* #2 */
}
}
for(int i=0;i<10;i++)
{
布尔b;/*#1*/
Console.WriteLine(b);//注意,如果您尝试
for (int i = 0; i < 10; i++)
{
bool b; /* #1 */
if (!b)
{
i = 100000;
}
if (i == 0)
{
b = true; /* #2 */
}
}
这意味着当方法加载到堆栈上时,它被分配了堆栈空间。它使用的空间在方法执行期间不会改变,因此它不会重置,除非你用类似b=default(typeof(bool));
的命令告诉它
for (int i = 0; i < 10; i++)
{
bool b; /* #1 */
if (!b)
{
i = 100000;
}
if (i == 0)
{
b = true; /* #2 */
}
}
这意味着当方法加载到堆栈上时,它会被分配堆栈空间。它使用的空间在方法执行期间不会改变,因此它不会重置,除非您用类似b=default(typeof(bool))的命令告诉它
说明局部变量的范围是在for
语句中,但是,您可能会发现编译器在所有迭代中都使用相同的变量作为优化,而不是每次都创建/丢弃相同的变量
话虽如此,如果您没有明确设置默认值,那么在下一次迭代中,b
实际上不会重置回false
。如果您为b
设置默认值,那么您应该发现您的代码按预期工作,事实上您无论如何都应该给它一个默认值;这不是一个尝试我建议依赖默认值,因为默认值可以更改
显式声明提供了更多的清晰性并提高了可读性。说明了局部变量的范围是在for
语句中,但是,您可能会发现编译器在所有迭代中重复使用相同的变量作为优化,而不是每次都创建/丢弃相同的变量。
话虽如此,如果您没有明确设置默认值,那么在下一次迭代中,b
实际上不会重置回false
。如果您为b
设置默认值,那么您应该发现您的代码按预期工作,事实上您无论如何都应该给它一个默认值;这不是一个尝试我建议依赖默认值,因为默认值可以更改
显式声明提供了更多的清晰性并提高了可读性。请注意,在代码中声明了
bool b;
您没有为声明的变量指定默认值,然后尝试在if条件块中将值指定给bool b;
,这会造成一些混乱
因此,首先要避免这种混淆,您必须将值赋给声明的变量bool b;
,声明后,它将让您清楚地了解默认值和您在循环中未来指定的值
比如bool b=True;或者bool b=False;
修改代码
for (int i = 0; i < 10; i++)
{
bool b = False; /* #1 */
if (i == 0)
{
b = true; /* #2 */
}
}
for(int i=0;i<10;i++)
{
bool b=False;/*#1*/
如果(i==0)
{
b=真;/*#2*/
}
}
请注意,您在代码中声明了
bool b;
您没有为声明的变量指定默认值,然后尝试在if条件块中将值指定给bool b;
,这会造成一些混乱
因此,首先要避免这种混淆,您必须将值赋给声明的变量bool b;
,声明后,它将让您清楚地了解默认值和您在循环中未来指定的值
比如bool b=True;或者bool b=False;
修改代码
for (int i = 0; i < 10; i++)
{
bool b = False; /* #1 */
if (i == 0)
{
b = true; /* #2 */
}
}
for(int i=0;i<10;i++)
{
bool b=False;/*#1*/
如果(i==0)
{
b=真;/*#2*/
}
}
在初始化为已知值之前,不能使用b,这又有什么关系呢?我想这是因为b实际上是在循环上方的方法中声明为局部的,所以它将保持其value@JamesBarrass“真的吗?我以为所有的结构都应该自动初始化为它们的默认值?”詹姆斯巴拉斯说,这主要是出于好奇。我想知道为什么编译器是这样工作的,为什么不问问呢?我不认为这是一个完全相同的问题,尽管主题肯定是相同的。我怀疑链接的问题能否提供OP寻求的答案。我找不到更好的副本,所以我投票重新打开这个问题。你不能使用