最初分配了以下两类变量:
类实例的实例变量。
最初分配的结构变量的实例变量。
现在最初分配的结构变量是什么意思?
我们不是在谈论局部变量,对吧?所以我们谈论的是在函数成员定义中使用的字段变量(在这两个类别中)?
澄清这一点将不胜感激。并提前感谢!
最初分配了以下两类变量:
类实例的实例变量。
最初分配的结构变量的实例变量。
现在最初分配的结构变量是什么意思?
我们不是在谈论局部变量,对吧?所以我们谈论的是在函数成员定义中使用的字段变量(在这两个类别中)?
澄清这一点将不胜感激。并提前感谢!
最初分配了以下两类变量:(1)类实例的实例变量和(2)最初分配的结构变量的实例变量。“最初分配的结构变量”是什么意思?
这意味着最初分配的结构类型变量。
跟着。
class C
{
public int i;
}
...
C c = new C();
Console.WriteLine(c.i);
c.i
是一个类的实例变量,所以它最初是赋值的。
struct S
{
public int j;
}
class D
{
public S t;
}
...
D d = new D();
Console.WriteLine(d.t.j);
d.t
是一个类的实例变量,所以最初是赋值的。d.t.j
是 struct 的实例变量,类型S
变量是初始分配的,因此也是初始分配的。d.t
S
d.t.j
也就是说,如果保存结构值的变量本身是初始分配的,则结构的字段是初始分配的。
相比之下:
void M()
{
int q;
Console.WriteLine(q); // Error
S u;
Console.WriteLine(u.j); // Error
既不q
是也不u
是最初分配的;它们不是任何类的字段。由于u
最初没有分配,u.j
因此也不是。
现在有意义吗?
你的问题不是很清楚。但是始终将类或结构的字段(实例或静态)视为已分配是正确的。它将具有类型的默认值,null
用于引用类型和可为空的类型,以及“零”或其他值类型类似于零的值。
相反,局部变量,即在方法(或构造函数,或访问器等)中声明的变量,必须在使用之前显式分配给它。
在示例中:
class Example
{
int field;
void Method()
{
int local;
...
...
}
}
被field
认为是自动分配的,并且将具有初始值0
,而变量local
是未分配的,必须先分配给(稍后在同一方法中),然后才能使用(甚至稍后在同一方法中)。
但是,未分配的局部变量可以作为out
方法的参数传递。
编辑:(在有用的评论后)
我上面的回答对类的(静态和非静态)字段和结构的静态字段给出了非常精确的描述。但是,正如评论所指出的,在结构的实例字段的情况下,缺少一些东西。
当结构实例的所有实例字段都被完全分配时,它就被完全分配了。给定以下(可变的!!)结构:
struct SomeStruct
{
public int AlphaField;
public int BetaField;
}
那么以下是合法的:
void M()
{
SomeStruct localSS;
// localSS and its fields are not assigned, and can't be read yet
localSS.AlphaField = 7; // legal
int useA = localSS.AlphaField; // legal, AlphaField is assigned
// localSS and its remaining field BetaField are not assigned
localSS.BetaField = 13;
string useB = localSS.ToString(); // legal, localSS variable is now fully assigned
}
即使上面的例子看起来很疯狂(因为大多数人不鼓励可变结构),它仍然完全等同于在结构的用户定义实例构造函数中发生的事情。C#规范使用了这样一句话:结构的实例构造函数的this
变量与结构类型的参数的行为完全相同out
——特别是,这意味着必须在实例构造函数的每个执行路径中明确地分配变量。
请注意,结构的实例构造函数分配所有字段的一种方法是使用: this(...)
构造函数链接语法链接另一个实例构造函数。
另请注意,结构的实例构造函数必须带参数。表达式new SomeStruct()
(带有空参数列表)等效于并计算为所有字段都具有其默认值default(SomeStruct)
的明确分配的实例。SomeStruct
类(在 C# 中)是引用类型的定义。这意味着该类的任何成员都存储为引用。
结构(在 C# 中)是值类型的定义。此类的任何成员都存储为值,而不是引用。
引用类型可以取消分配,因为在使用它们之前不需要分配它们。使用未分配的类实例成员会导致运行时错误。
值类型需要一个值来存储,因为否则它们将无法确定它们的内存空间。使用未分配的结构成员会导致编译时错误。