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 仍然是一个结构。
现在是问题。
- CLR 是否为 class 对象的每个字段引用生成一个 "if (x == null)" 语句,或者它是如何生成的?
- 当参数是结构时,CLR 是否对 ref 参数执行相同的操作?
- 当 CS 是一个结构时,是否可以为 CS 参数获取 null?
结构是值类型,因此它们不为空。 (您必须将其设置为 Nullable<CS>
,因为值类型不能为空 - 请参阅 Nullable docs)
default(CS)
是一个结构,其中 X
(另一种值类型)是 0
(或更准确地说,default(int)
)。结构中的所有字段都初始化为 default(FieldType)
.
有关结构的更多信息,请查看 the documentation。
因为C#中的struct
是value-type
,不能是null
。您可以使用 Nullable<YourStruct>
然后使用 HasValue
属性 检查它是否刚刚初始化。
并且结构总是被初始化。如果不是您,则由编译器使用默认值。
您问题的答案:
- 取消引用以获取成员的引用的行为将引发异常。没有添加 explicit 或 * implicit* if 语句,但效果是一样的。
- 不,不是。
struct
变量永远不能为空。编译器知道这一点。
- 不,
ref struct X
参数永远不能为 null,您不是在引用结构,而是在引用包含该结构的变量。您无法编译在调用该方法时不引用变量的代码,因此不需要。
如果您要使用指针,那么是的,即使是指向结构的指针也可能出现空值,但 ref
参数则不会。
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 仍然是一个结构。
现在是问题。
- CLR 是否为 class 对象的每个字段引用生成一个 "if (x == null)" 语句,或者它是如何生成的?
- 当参数是结构时,CLR 是否对 ref 参数执行相同的操作?
- 当 CS 是一个结构时,是否可以为 CS 参数获取 null?
结构是值类型,因此它们不为空。 (您必须将其设置为 Nullable<CS>
,因为值类型不能为空 - 请参阅 Nullable docs)
default(CS)
是一个结构,其中 X
(另一种值类型)是 0
(或更准确地说,default(int)
)。结构中的所有字段都初始化为 default(FieldType)
.
有关结构的更多信息,请查看 the documentation。
因为C#中的struct
是value-type
,不能是null
。您可以使用 Nullable<YourStruct>
然后使用 HasValue
属性 检查它是否刚刚初始化。
并且结构总是被初始化。如果不是您,则由编译器使用默认值。
您问题的答案:
- 取消引用以获取成员的引用的行为将引发异常。没有添加 explicit 或 * implicit* if 语句,但效果是一样的。
- 不,不是。
struct
变量永远不能为空。编译器知道这一点。 - 不,
ref struct X
参数永远不能为 null,您不是在引用结构,而是在引用包含该结构的变量。您无法编译在调用该方法时不引用变量的代码,因此不需要。
如果您要使用指针,那么是的,即使是指向结构的指针也可能出现空值,但 ref
参数则不会。