我正在阅读MCTS Self Paced Training Kit(70-536)Edition 2,在第1章我们有以下内容。
如何声明值类型变量 要使用类型,必须先声明 符号作为该类型的实例。 值类型具有隐含性 构造函数,所以声明它们 自动实例化类型; 你不必包括新的 关键字与关键字一样。该 构造函数指定默认值 (通常为null或0)到新的 例如,但你应该永远 显式初始化变量 在声明中,如图所示 以下代码块:
'VB
Dim b As Boolean = False
// C#
bool b = false;
但是,当我编译以下控制台应用程序时,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ch1_70_536
{
class Program
{
static void Main(string[] args)
{
bool b;
Console.WriteLine("The value of b is " + b);
Console.ReadKey();
}
}
}
我收到编译时错误
“使用未分配的本地变量b”
Errata中甚至没有提到它。我做错了还是这本书完全错了?
答案 0 :(得分:13)
必须先分配局部变量才能使用它们。但是,类字段会获得默认值。
一个例子:
public bool MyMethod()
{
bool a;
Console.Write(a); // This is NOT OK.
bool b = false;
Console.Write(b); // This is OK.
}
class MyClass
{
private bool _a;
public void MyMethod()
{
Console.Write(_a); // This is OK.
}
}
答案 1 :(得分:11)
这本书在VB方面基本上是正确的,但在这种情况下它没有提到VB和C#之间的区别。
在VB中,所有局部变量都会自动初始化:
Sub Test()
Dim x As Integer
MessageBox.Show(x.ToString()) 'shows "0"
End Sub
虽然在C#中局部变量没有初始化,但编译器不允许你使用它们:
void Test() {
int x;
MessageBox.Show(x.ToString()); // gives a compiler error
}
此外,还不清楚本书中的引用是否实际上是在讨论局部变量或类成员变量。在VB和C#中创建类实例时,始终会初始化类成员变量。
当它说“值类型具有隐式构造函数”时,这本书是错误的。那明显是错的。值类型初始化为其默认值(如果已初始化),并且在发生这种情况时不会调用构造函数。
答案 2 :(得分:4)
你需要首先给b分配一些东西,否则它不会被初始化。
尝试:
bool b = false;
Console.WriteLine("The value of b is " + b);
b现在是假的。
答案 3 :(得分:2)
您需要为b
bool b = false;
在为其分配值之前,它是“未分配的”
答案 4 :(得分:2)
需要显式初始化方法中的变量(方法范围)。类级别的变量(或“字段”)将使用默认值自动初始化。
class Test
{
bool b; // =false
int i; // =0
}
答案 5 :(得分:2)
确保THUMB在C#和VB.net中的角色,在调用任何变量之前,首先启动它。 像
int myInt; // Simple Declaration and have no value in it
myInt= 32; // Now you can use it as there is some value in it..
答案 6 :(得分:1)
这个陈述确实应该详细说明,虽然一个局部变量可以声明而不给它赋值,但是在它被赋值之前它不能使用初始值:
构造函数为新实例分配一个默认值(通常为null或0),但是你应该始终在声明中显式初始化变量......
答案 7 :(得分:0)
在C#中,局部变量存储在堆栈中,编译器不会初始化它们以进行代码优化。
因此,引用(实际上甚至是值类型的指针)都指向未定义的存储空间。
因此,如果我们使用局部变量之前未将其设置为Someting,则编译器知道我们将获得随机数据。
以下是示例IL代码:
static void Test()
{
int a;
int b = 2;
}
.method private hidebysig static
void Test () cil managed
{
// Method begins at RVA 0x3044
// Code size 4 (0x4)
.maxstack 1
.locals init (
[0] int32 a,
[1] int32 b
)
// (no C# code)
IL_0000: nop
// int num = 2;
IL_0001: ldc.i4.2
IL_0002: stloc.1
// }
IL_0003: ret
} // end of method Program::Test
Int32
在堆栈中的0
位置a
中定义,但未分配为默认值。
因此它的值不确定,可以从存储单元中获取任何值。
对于位置b
上的1
,稍后分配它,一切都很好。