c# - 将 null 分配给类的实例和仅声明之间有什么区别

标签 c# null declaration

我试图了解将 null 分配给类的实例和仅声明类之间是否有任何区别。

例如,我有一个类:

public class MyClass
{
    public string FirstProperty { get; set; }
    public int SecondProperty { get; set; }
}

我声明了该类的两个实例:
MyClass Instance1 = null;
MyClass Instance2;  // just declaration
Instance1 之间有什么区别吗?和 Instance2 ?

如果是,它安全吗?使用 'delcaration only' 样式是否是一个好习惯(如上例中 Instance2 的情况)?

最佳答案

Then I'm creating two instances of the class:



您没有创建任何实例。如果曾经创建过实例,您将创建两个放置实例的位置。您明确表示的第一个没有实例,第二个只是没有实例。

Is there any difference between Instance1 and Instance2?



这取决于你在哪里做的。

如果该代码在 class 内或 struct那么您已经创建了两个字段,这两个字段都将设置为 null最初,除非构造函数执行其他操作。

如果您在方法中包含该代码(包括构造函数或属性访问器),那么您将获得两个局部变量(尽管此处的约定是使用小写字母)。

第一个已设置为 null 并且您可以使用它执行对 null 有效的操作(将其传递给方法 [尽管如果它拒绝接受 null,它可能会引发异常)将其与某些东西进行比较以确认它是确实为 null 或确实与确实有实例的东西不同。

第二个没有被分配,因此除了给它分配一些东西(无论是空的还是实例)之外,做任何事情都是非法的。在确定设置之前任何尝试做任何事情都将是编译器错误。例如。:
MyClass Instance2;
if (valueThatJustHappensToAlwaysBeTrue)
{
   Instance2 = new MyClass();
}
bool isNull = Instance2 == null; // Error! Not guaranteed to be assigned strongly enough for the compiler to know.

Is yes, is it safe and it's a good habit to have Instance2 with declaration only?



在可能的情况下,最好在尽可能接近第一个赋值(初始化)时声明,最好是同时声明:
MyClass instance = new MyClass();

但是,如果您有几种不同的可能路径,例如:
MyClass instance;
if (boolValue)
{
   instance = new MyClass(1); // Yes, I know there's no int-taking ctor on your class, but it defeats the argument when the bare constructor is the only one available, so let's say there is.
}
else if (otherBoolValue)
{
   throw new SomeException();
}
else if (someIntValue > 42)
{
   instance = new MyClass(3);
}
else
{
   instance = new MyClass(9);
}

现在,用未初始化的 instance 到达这条链的末尾是不可能的。 .要么已设置,要么已抛出异常。如果我们认为从 MyClass instance = null 开始可能更“安全”那么我们可能隐藏了一个错误。上面的逻辑旨在为每个路径分配一些东西,并且由于您不能使用不能保证分配的实例的规则,因此错误会导致编译器错误,并且错误会很明显.如果将它分配给“占位符” null 以开始这样的错误不会那么明显,并且可能导致错误。

所以在像裸声明这样的情况下更好。

但话虽如此,在可能的情况下总是最好避免复杂的逻辑,所以那些复杂的链应该很少见。在其他情况下,在同一点声明和分配的风格意味着您在两者之间没有可能出现错误的间隙。

关于c# - 将 null 分配给类的实例和仅声明之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41898339/

相关文章:

C# - 命名空间内的类型声明

c# - Visual Studio 调试器问题

c - 字符串末尾的空字符 '\0'

hadoop - 将 HIVE 查询结果中的空值或 NULL 值替换为特定值

c# - 在重写 Equals 中进行空检查之前转换为对象

php - PHP中是否有类似于VB中的Option Explicit的东西

c++ - C++使用三元运算符声明变量

c# - 如何编写基于验收的测试(从代码的角度来看)

c# - 如何将实现某个通用接口(interface)的所有类型放入字典中?

c# - XML 序列化 Roslyn SyntaxTree?