我一直想知道为什么在下面的示例中,对于 not来说可以 初始化实例字段(依靠它具有默认值)并访问它,而局部变量显然是 must 被初始化,即使我将其初始化为默认值也仍然会得到...
public class TestClass
{
private bool a;
public void Do()
{
bool b; // That would solve the problem: = false;
Console.WriteLine(a);
Console.WriteLine(b); //Use of unassigned local variable 'b'
}
}
- 2021-1-111 #
- 2021-1-112 #
它受C#中的"确定分配"规则支配.必须先明确分配变量,然后才能对其进行访问。
5.3 Definite assignment
At a given location in the executable code of a function member, a variable is said to be definitely assigned if the compiler can prove, by a particular static flow analysis (§5.3.3), that the variable has been automatically initialized or has been the target of at least one assignment.
5.3.1 Initially assigned variables
The following categories of variables are classified as initially assigned:
Static variables.
Instance variables of class instances.
Instance variables of initially assigned struct variables.
Array elements.
Value parameters.
Reference parameters.
Variables declared in a catch clause or a foreach statement.
5.3.2最初未分配的变量
以下类别的变量分类为最初未分配的变量:
Instance variables of initially unassigned struct variables.
Output parameters, including the this variable of struct instance constructors.
Local variables, except those declared in a catch clause or a foreach statement.
为新对象实例分配了一块内存时,运行时会在整个块上写入零,以确保新对象以已知状态开始-这就是为什么整数默认为0,双精度默认为0.0, 指向null的指针和对象引用,等等。
理论上,可以对作为方法调用的一部分分配的帧进行相同的处理.尽管开销会很高-可能会增加 会减慢对其他方法的调用,因此不会尝试。
- 2021-1-113 #
实例变量具有默认值.根据C#3.0规范:
drastically p这是编译器的限制.编译器会尝试阻止您尽可能使用未分配的变量,这是一件好事,因为使用未初始化的变量曾经是旧C代码中常见的错误源.
但是,编译器无法在调用该方法之前知道实例变量是否已初始化,因为它可以由任何其他方法设置,可以由外部代码以任何顺序调用。
5.1.2.1 Instance variables in classes
An instance variable of a class comes into existence when a new instance of that class is created, and ceases to exist when there are no references to that instance and the instance’s finalizer (if any) has executed.
The initial value of an instance variable of a class is the default value (§5.2) of the variable’s type.
For the purpose of definite assignment checking, an instance variable is considered initially assigned.
相关问题
- c#:NET 40和可怕的OnUserPreferenceChanged挂起c#netmultithreadingclrdeadlock2021-01-11 12:56
- c#:遍历函数结果时,foreach如何工作?c#netforeach2021-01-11 17:26
- c#:PictureBox问题c#netwinformspicturebox2021-01-11 04:56
- c#:并行执行任务c#netasynchronousasyncawaittaskparallellibrary2021-01-11 04:56
- c#:静态和实例方法同名?c#netoop2021-01-11 05:55
对于局部变量,编译器对流程有很好的了解-它可以看到变量的"读取"和变量的"写入",并(在大多数情况下)证明 首次写入将在首次读取之前进行。
实例变量不是这种情况.考虑一个简单的属性-您如何知道是否有人会在获得它之前对其进行设置? 这使得强制实施明智的规则基本上不可行-因此,您必须确保在构造函数中设置了all字段,或者允许它们具有默认值. C#团队选择了后一种策略。