CLR 中的空引用检查

null reference checking in CLR

C#中CLR空引用检查的一些问题

考虑一下:

class CS
{
  public int X;
}

void Foo(CS c)
{
  c.X += 10;
}

CS c = default(CS);

Foo(c);

显然这里抛出了 NullReferenceException。

现在 CS 变成了一个结构体

struct CS { public int X; }

CS c = default(CS);

Foo(c);

现在没有抛出异常

然后 Foo 变为采用 ref CS cs 参数。

void Foo(ref CS c) { c.X += 10; }

同样也不例外,因为 CS 仍然是一个结构。

现在是问题。

  1. CLR 是否为 class 对象的每个字段引用生成一个 "if (x == null)" 语句,或者它是如何生成的?
  2. 当参数是结构时,CLR 是否对 ref 参数执行相同的操作?
  3. 当 CS 是一个结构时,是否可以为 CS 参数获取 null?

结构是值类型,因此它们不为空。 (您必须将其设置为 Nullable<CS>,因为值类型不能为空 - 请参阅 Nullable docs

default(CS) 是一个结构,其中 X(另一种值类型)是 0(或更准确地说,default(int))。结构中的所有字段都初始化为 default(FieldType).

有关结构的更多信息,请查看 the documentation

因为C#中的structvalue-type,不能是null。您可以使用 Nullable<YourStruct> 然后使用 HasValue 属性 检查它是否刚刚初始化。 并且结构总是被初始化。如果不是您,则由编译器使用默认值。

您问题的答案:

  1. 取消引用以获取成员的引用的行为将引发异常。没有添加 explicit 或 * implicit* if 语句,但效果是一样的。
  2. 不,不是。 struct 变量永远不能为空。编译器知道这一点。
  3. 不,ref struct X 参数永远不能为 null,您不是在引用结构,而是在引用包含该结构的变量。您无法编译在调用该方法时不引用变量的代码,因此不需要。

如果您要使用指针,那么是的,即使是指向结构的指针也可能出现空值,但 ref 参数则不会。