C# 可为空<;=vs==比较结果
我觉得这种行为是不对的C# 可为空<;=vs==比较结果,c#,comparison,operator-keyword,nullable,C#,Comparison,Operator Keyword,Nullable,我觉得这种行为是不对的 DateTime? birth = null; DateTime? death = null; Console.WriteLine(birth == death); // true Console.WriteLine(birth <= death); // false 这是完全可以理解的行为。但是看看逻辑: 根据ECMA-334标准(8.19可空类型)(强调矿山): 比较运算符(=,!=,,=)在操作数类型均为不可空值类型且结果类型为空时具有提升形式 bool
DateTime? birth = null;
DateTime? death = null;
Console.WriteLine(birth == death); // true
Console.WriteLine(birth <= death); // false
这是完全可以理解的行为。但是看看逻辑:
根据ECMA-334标准(8.19可空类型)(强调矿山): 比较运算符(
,=
,!=
,
)在操作数类型均为不可空值类型且结果类型为空时具有提升形式=
。比较运算符的提升形式是通过添加bool
每个操作数类型的修饰符(但不是结果类型)。?
和==
=代码> 运算符认为两个空值相等,空值不等于非空值。
,
如果一个或两个操作数都为null,则运算符返回false=
我理解你不是在寻找规范,而是在寻找一个解释为什么nullables是这样设计的 为了消除歧义,设计者可以让这些运算符返回一个
值,而不是bool?
值,如果其中一个操作数为空,该值将为空 但如果他们做出了这个选择,代码将如下所示:bool
bool? comparison = birth <= death; if (comparison.HasValue && comparison.Value) { }
bool?比较=出生你是在问为什么语言是这样设计的,还是想证明你看到的行为符合语言?@JonSkeet为什么语言是这样设计的:)我只是不明白为什么它会这样做……在这种情况下,false意味着“未知”。设计者可能已经实现了比较运算符(不包括==和!=),以便它们返回一个可为空的布尔结果,而不是布尔结果,但是使用它们的代码的可读性显然会受到影响。我想他们更喜欢用这种方式实现它,尽管可能会有一些角落案例被清楚地记录在案。@vc74请参见编辑:)@Randolph birth
death返回false,因为其中一个变量为null。“birth=DateTime.Now”的结果将为false bool? comparison = birth <= death; if (comparison.HasValue && comparison.Value) { }
.method private hidebysig static void Main(string[] args) cil managed { .locals init ([0] valuetype [mscorlib]System.Nullable`1<int32> x, [1] valuetype [mscorlib]System.Nullable`1<int32> V_1, [2] valuetype [mscorlib]System.Nullable`1<int32> V_2) IL_0000: ldloca.s x IL_0002: ldc.i4.1 IL_0003: call instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0) IL_0008: ldc.i4.2 IL_0009: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0) IL_000e: ldloc.0 IL_000f: stloc.1 IL_0010: stloc.2 IL_0011: ldloca.s V_1 IL_0013: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault() IL_0018: ldloca.s V_2 IL_001a: call instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault() IL_001f: ble.s IL_0024 IL_0021: ldc.i4.0 IL_0022: br.s IL_0033 IL_0024: ldloca.s V_1 IL_0026: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue() IL_002b: ldloca.s V_2 IL_002d: call instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue() IL_0032: and IL_0033: brfalse.s IL_003a IL_0035: call void [mscorlib]System.Console::WriteLine() IL_003a: ret } // end of method Program::Main