C# &引用;ulong==ulong?“;评价为;ulong==ulong";工作正常
如果在C# &引用;ulong==ulong?“;评价为;ulong==ulong";工作正常,c#,operator-overloading,nullable,equals-operator,C#,Operator Overloading,Nullable,Equals Operator,如果在ulong表达式和ulong?表达式之间使用==运算符,则会使用运算符重载bool ulong(ulong left,ulong right) 换句话说,操作符认为这两个表达式都是非null的 在这个示例程序中,equal正确地变为false,没有例外 void Main() { var temp = new Temp(0); object temp2 = null; var equal = temp.Id == (temp2 as Temp)?.Id; //
ulong
表达式和ulong?
表达式之间使用==
运算符,则会使用运算符重载bool ulong(ulong left,ulong right)
换句话说,操作符认为这两个表达式都是非null的
在这个示例程序中,equal
正确地变为false,没有例外
void Main()
{
var temp = new Temp(0);
object temp2 = null;
var equal = temp.Id == (temp2 as Temp)?.Id; // False :) but how?
}
public class Temp
{
public ulong Id {get;}
public Temp(ulong id)
{
this.Id = id;
}
}
ulong?
转换为ulong
(ulong)(ulong?)null
抛出:“可为null的对象必须有一个值。”ulong?
的每个可能值返回正确的值,包括null?如果是,怎么做?类型ulong?
比ulong
多了一个可能值,因此应该有一组两个值映射到相同的ulong
值,这将引入一个假阳性“真”结果default(ulong)
,但是我上面的例子中的结果是真的,这是一个不正确的答案。正如我们所看到的,编译器没有犯这样的错误——它正确地回答了问题。来自:
提升运算符允许对不可空值类型进行操作的预定义和用户定义的运算符也与这些类型的可空形式一起使用。提升操作器由满足特定要求的预定义和用户定义的操作器构成,如下所述:
- 对于等式运算符
== !=
bool
,则存在运算符的提升形式。提升形式是通过向每个操作数类型添加单个?
修饰符来构造的。提升运算符认为两个空值相等,一个空值不等于任何非空值。如果两个操作数都不为空,则提升运算符将展开操作数并应用基础运算符以生成bool
结果
您没有使用运算符:
bool ==(ulong left, ulong right)
bool ==(ulong? left, ulong? right)
您正在使用提升操作符:
bool ==(ulong left, ulong right)
bool ==(ulong? left, ulong? right)
此运算符接受两个ulong?
参数,如果两个参数均为null,或者如果两个参数均为非null且具有相同的值,则返回true
您可能正在查看Visual Studio,它确实向您展示了一些令人困惑的东西: 不要对此感到困惑——正如@mjwills在评论中指出的那样
如果你这样写:
public bool M(ulong a, ulong? b) {
return a == b;
}
然后编译器生成以下代码:
public bool M(ulong a, ulong? b)
{
ulong? num = b;
return (a == num.GetValueOrDefault()) & num.HasValue;
}
num.GetValueOrDefault()
如果b
为null
,则返回0
,否则返回b
的值。因此M
返回true
当且仅当b
不为空,并且与a
具有相同的值
如果我们在ulong表达式和
表示ulong?,然后运算符重载bool ulong(ulong
使用左,右(右)
问题的很大一部分是Visual Studio的intellisense错误地显示了正在使用的ulong
运算符(如果将鼠标悬停在=
上)
根据,这是一个bug。它实际上并没有使用那个操作符
由于您的所有其他问题都基于该错误前提,因此意识到该错误的存在会使其他问题基本消失。
(temp2作为Temp)?.Id
返回一个ulong?
,该参数可用于解释所有问题。我不知道有什么人。谢谢你详尽的回答!