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