C# 在.net中,可空类型是如何在后台实现的?

C# 在.net中,可空类型是如何在后台实现的?,c#,.net,nullable,C#,.net,Nullable,在我们自己的Jon Skeet中,他讨论了3种模拟值类型“null”的方法: 神奇值(例如,最早的日期时间被视为“null”) 引用类型包装器 布尔标志 提到了可空类型使用第三种方法。可空类型到底是如何在后台工作的?归根结底,它们只是一个带有bool标志的泛型结构——除了特殊的装箱规则。因为结构(默认)初始化为零,所以bool默认为false(无值): public结构可为null,其中T:struct{ 私有只读T值; 私有只读布尔值; 公共可为空(T值){ 这个值=值; hasValue

在我们自己的Jon Skeet中,他讨论了3种模拟值类型“null”的方法:

  • 神奇值(例如,最早的日期时间被视为“null”)
  • 引用类型包装器
  • 布尔标志

提到了可空类型使用第三种方法。可空类型到底是如何在后台工作的?

归根结底,它们只是一个带有bool标志的泛型结构——除了特殊的装箱规则。因为结构(默认)初始化为零,所以bool默认为false(无值):

public结构可为null,其中T:struct{
私有只读T值;
私有只读布尔值;
公共可为空(T值){
这个值=值;
hasValue=true;
}
公共价值{
得到{
如果(!hasValue)引发一些异常;-p
返回值;
}
}
public T getValuerDefault(){return value;}
公共bool HasValue{get{return HasValue;}}
公共静态显式运算符T(可空值){
返回值。值;}
公共静态隐式运算符可为null(T值){
返回新的可为空(值);}
}
不过,还有其他区别:

  • 特殊拳击规则(你通常不能这么做)
  • 比较空值等的特殊C#规则
  • C#中的“提升”运算符(以及在.NET中通过
    EqualityComparer
    Comparer
    等)
  • 关于泛型类型约束的特殊规则(防止
    可为null
Nullable
通过提供两个字段来工作:

private bool hasValue;
internal T value;

属性从这些属性开始工作。如果您将其设置为
null
,hasValue将设置为false。

无耻的插件:我不久前写了一篇关于其工作原理的博文:@FredrikMörk该链接不再可用。..@M.Mimpen现在它又可用了。那个博客不久前就崩溃了,但我已经在其他地方重新发布了,但是已经重定向到了原来的url?我可以为自己的结构实现自己的装箱规则吗?它由CLI中的特殊规则处理。不,你不能自己做。同样,“提升”操作符也不是你自己能做的事情。同样值得注意的是,操作符的行为受语言控制——C#和VB对不同的操作符有不同的规则。我只是遇到了一个不同点:你可以给
t?
方法参数一个默认值
t
,但是,如果您实现自己的nullable类型并尝试执行相同的操作,则会出现编译错误。(例如,“不能将'bool'类型的值用作默认参数,因为没有到'MyNullable'类型的标准转换。)这是否属于您的项目符号之一?但这不仅仅是可能的,因为
T
以及
Nullable
都是无结构的,并且结构不能轻松设置为
null
private bool hasValue;
internal T value;