然后我创建了该类的两个实例:
您并没有创建任何实例。您只是创建了两个位置,以便在必要时放置实例。您已经明确表示第一个位置没有实例,而第二个位置则没有实例。
“Instance1”和“Instance2”之间有什么区别吗?
这取决于您将代码放在哪里。
如果该代码位于“class”或“struct”中,则您已经创建了两个字段,这两个字段最初都将设置为“null”,除非构造函数执行其他操作。
如果您将该代码放在方法中(包括构造函数或属性访问器),则您将拥有两个局部变量(尽管约定使用小写字母)。第一个变量已设置为null,您可以对其进行有效的null处理(将其传递给方法[虽然它可能会抛出异常,如果它拒绝接受null)与某些内容进行比较,以确认它确实为null或确实与真正拥有实例的某个东西不同。
第二个未被分配,因此禁止在它被确定之前执行除分配任何值外的任何操作(无论是null还是实例),否则任何尝试都将导致编译错误。例如:
MyClass Instance2
if (valueThatJustHappensToAlwaysBeTrue)
{
Instance2 = new MyClass()
}
bool isNull = Instance2 == null
如果是的话,仅声明Instance2
是否安全且是一个好习惯?
尽可能地,在第一次赋值(初始化)时,最好在声明附近进行声明,理想情况下应同时进行:
MyClass instance = new MyClass()
然而,如果你有几条不同的可能路径,比如:
MyClass instance;
if (boolValue)
{
instance = new MyClass(1);
}
else if (otherBoolValue)
{
throw new SomeException();
}
else if (someIntValue > 42)
{
instance = new MyClass(3);
}
else
{
instance = new MyClass(9);
}
现在,如果一个未初始化的
instance
无法到达链的末端。它要么已被设置,要么异常将被抛出。如果我们认为从
MyClass instance = null
开始可能更加“安全”,那么我们可能会隐藏一个错误。上面的逻辑意味着为每条路径分配了一个东西,因为规则规定不能使用未经保证分配的实例,所以在这方面的错误会导致编译器错误,并且错误会很明显。如果一开始就被分配给一个“占位符”null,这样的错误不会那么立即显而易见,可能会导致一个bug。
所以,在像光秃声明这样的情况下,更好。
但是话说回来,当可能时,应该尽量避免复杂的逻辑,因此这些复杂的链应该是罕见的。在其他情况下,声明和赋值在同一点的风格意味着两者之间没有差距,因此不会出现错误。
null
,后者是一个没有明确初始化的变量,因此会获得默认值,也是null
。区别在于可读性,每个人都知道null
是期望的和预期的。如果您有一个out
参数,编译器会强制您分配某些东西,即使它是null
。 - Tim Schmelternull
赋值。 - Fabio