CLR中的空引用检查

本文关键字:引用 检查 CLR | 更新日期: 2023-09-27 17:49:47

关于c#中CLR空引用检查的几个问题

考虑一下:

class CS
{
  public int X;
}
void Foo(CS c)
{
  c.X += 10;
}
CS c = default(CS);
Foo(c);

显然这里抛出了一个NullReferenceException。

现在CS变成了struct

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是否为类对象的每个字段引用生成"if (x == null)"语句,或者它是如何做到的?
  2. 当参数是一个结构体时,CLR是否对ref参数做同样的处理?
  3. 当CS是一个结构时,是否有可能获得CS参数为空?

CLR中的空引用检查

struct是值类型,所以它们不是空的。(你必须让它成为Nullable<CS>,因为值类型不能为空-参见可空文档)

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

有关结构的更多信息,请查看文档

回答你的问题:

  1. 解除引用以获得成员的行为将抛出异常。没有添加显式或*隐式* if-语句,但效果是一样的。
  2. 没有。struct变量永远不能为空。编译器知道这个。
  3. 不,ref struct X参数永远不能为空,你不是在引用结构体,你引用的是保存结构体的变量。当调用该方法时,你不能编译没有引用变量的代码,因此没有必要。

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

因为c#中的structvalue-type,所以不可能是null。您可以使用Nullable<YourStruct>,然后使用HasValue属性来检查它是否刚刚初始化。结构体总是初始化的。