C# 可空类型上的方法
有人能解释一下为什么可以在C# 可空类型上的方法,c#,nullable,C#,Nullable,有人能解释一下为什么可以在null实例上调用方法吗 int? num = null; var s1 = num.ToString(); var s2 = num.HasValue; var s3 = num.GetHashCode(); var s4 = num.GetValueOrDefault(); var s5 = num.Value; // InvalidOperationException var s6 = num.GetType(); // NullReferenceExcept
null
实例上调用方法吗
int? num = null;
var s1 = num.ToString();
var s2 = num.HasValue;
var s3 = num.GetHashCode();
var s4 = num.GetValueOrDefault();
var s5 = num.Value; // InvalidOperationException
var s6 = num.GetType(); // NullReferenceException
我可以在调试模式下检查num
是否为null
,那么ToString
方法或HasValue
getter怎么可能在null
实例上调用,但对于Value
和GetType
则不可能?它们都是Nullable
类型上的方法或属性,还是不是
我自然希望Value
getter返回null
值,类似于HasValue
返回false
。我也希望,GetType
返回Nullable
类型信息,或者num为int?
或者num为Nullable
有效。为什么不起作用?如何检查num
是否为可空类型
创建实例不会改变以下方面的任何内容:
Nullable<int> num = new Nullable<int>();
Nullable num=new Nullable();
幕后是什么?Nullable
有一点编译器魔法,使它看起来好像有一个null
值。但是没有。基本上,由于Nullable
是一种值类型,因此它一开始就不能是null
。它的可空性取决于是否存在值。这意味着您可以调用HasValue
(这很重要,因为这是编译器在编写num==null
时插入的)和其他不依赖于存在值的方法
关于几个具体问题:
是一种实现,其工作原理与ToString
值在字符串串联中使用时转换为字符串的方式类似,即生成空字符串。您也不希望null
抛出ToString
是将GetHashCode
作为键放入字典或将其放入哈希集中所必需的。它也不应该抛出,所以当没有价值时,它必须返回一些合理的东西Nullable
- 本文解释了一些基本概念
GetType
时隐式发生的情况:
编译器可以用typeof(SomeT?
)悄悄地替换nullableValue.GetType()
,这似乎是合乎逻辑的,但这意味着与其他编译器相比,它总是给出令人困惑的答案
object obj = nullableValue;
Type type = obj.GetType()
您可能希望它也能像这样工作,但是obj.GetType()
总是返回typeof(T)
(不是typeof(T?
),或者抛出NullReferenceException
,因为T?
框指向T
或null
(并且您不能询问null
它是什么类型)
编译器专门处理的结构映射有以下几点:
num == null → !num.HasValue
num != null → num.HasValue
num = null → num = new Nullable<int>()
num = 5 → num = new Nullable<int>(5)
(int) num → num.Value
(object) num → (object) num.Value // if HasValue
→ (object) null // if !HasValue
num==null→ !数值
num!=无效的→ 数值
num=null→ num=新的可空()
num=5→ num=新的可为空(5)
(int)num→ 数值
(对象)num→ (对象)num.Value//if HasValue
→ (对象)null//if!HasValue
还有对操作符的额外支持,最重要的是比较操作符与不可为null的
T
s以及处理潜在null
值(如?
)的各种操作符,但这是它的要点。不是真正的答案,只是一个注释。你写道:
我自然希望Value
getter返回null
值
不!
Nullable
存在的原因就是为了保护您不必先检查就可以获得null
值。从文档开始。Nullable.ToString
:“如果HasValue属性为true,则当前可为null对象的值的文本表示形式;如果HasValue属性为false,则为空字符串(“”)。Nullable
是一个结构,因此实际上不能为null
。这是编译器的特殊处理,使您能够执行int?num=null
首先。主要是的副本。它已经解释了为什么ToString
可以工作和GetType
抛出NullReferenceException
的核心问题,并解决了为什么GetType
返回空引用异常的问题,请阅读。基本上,这是一种将null
装箱的尝试。是的,装箱/取消装箱的基本行为解释了这一点。谢谢,但是我仍然认为请求一个类型并得到一个空的异常是不直观的。另外,Value
是一个t
必须是一个值类型,所以它不能是null
。另外,。Value
被键入为t
,所以根据定义它永远不能返回null
(因为您不能将设为null
);值得注意的是.GetValueOrDefault()
返回而不失败Joey:我想说的是,这正是有帮助的事情,也是创建Nullable
的原因。我认为它的存在不是为了保护您,而是允许您在不能保存null值的类型上使用null值(从db或json端点获取),但是,是的,我稍微改变了对值getter的理解。基础值包含不能为null的原始值,因此通过值getter读取值不能返回null。这似乎是合乎逻辑的。