考虑以下代码:
for (int i = 0; i < 10; i++)
{
bool b; /* #1 */
if (i == 0)
{
b = true; /* #2 */
}
}
我在#1和#2处设置了断点。
第一次 (i = 0),b 在 #1 处设置为 false,在 #2 处设置为 true。
第二次 (i = 1),b 在 #1 处为真。
这对我来说没有意义,因为我假设在第二个循环(i = 1)中开始时,b 在声明时应该再次为 false。
我假设第二个循环中 #1 处 b = false。
有谁愿意解释一下吗?
b
值无效。 C# 要求先初始化或分配所有局部变量,然后才能读取它们。因此,您在 Visual Studio 的调试器中看到的值是无用的,因为它无法读取。无法编写一段 C# 代码来“看到”该值在第二次迭代中设置为
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 */
}
}
如果向
false
添加显式初始化,则上面的代码将编译。调试器也会在断点处显示
false
。
for (int i = 0; i < 10; i++)
{
bool b; /* #1 */
if (!b)
{
i = 100000;
}
if (i == 0)
{
b = true; /* #2 */
}
}
你会得到一个编译错误,因为变量必须在使用前初始化
但是为了你的好奇心......
如果您查看 IL,您会注意到 b 被声明为本地。
.maxstack 2
.locals init (
[0] int32 i,
[1] bool b,
[2] bool CS$4$0000
)
这意味着当方法加载到堆栈时就分配了堆栈空间。它使用的空间在方法执行期间不会改变,因此它不会重置
除非你用类似b = default(typeof(bool));
之类的东西告诉它
规定局部变量的作用域是在 for
语句内,但是,您可能会发现编译器在所有迭代中重复使用相同的变量作为优化,而不是创建/丢弃每次都使用相同的变量。
话虽如此,假设您没有明确设置默认值,那么
b
实际上不会在下一次迭代中重置回
false
是有道理的。如果您为 b
设置了默认值,那么您应该会发现您的代码按预期工作,并且事实上您 应该无论如何都给它一个默认值;依赖默认值不是一个好主意,因为这些可以更改。 显式声明更加清晰并提高可读性。
bool b;
并且您没有为该声明的变量分配默认值,然后尝试在 if 条件块中为
bool b;
分配值,这只会造成一些混乱。
因此,首先要避免这种混乱,您必须在声明变量后将值分配给声明的变量
bool b;
,这将使您清楚地了解默认值和您在循环中将来分配的值
喜欢
bool b = True; or bool b = False;
修改代码
for (int i = 0; i < 10; i++)
{
bool b = False; /* #1 */
if (i == 0)
{
b = true; /* #2 */
}
}