"ulong == ulong?" 评估为 "ulong == ulong" 工作正常
"ulong == ulong?" evaluated as "ulong == ulong" works correctly
如果我们在 ulong
表达式和 ulong?
表达式之间使用 ==
运算符,则似乎使用了运算符重载 bool ulong(ulong left, ulong right)
。
换句话说,运算符认为两个表达式都是非空的。
在此示例程序中,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;
}
}
- 这怎么能不扔呢?没有从值为 null 的
ulong?
到 ulong
的转换。 (ulong)(ulong?)null
抛出:"Nullable object must have a value."
- 这个 return
ulong?
的每个可能值 的正确值是否正确,包括 null?如果是这样,如何?类型 ulong?
比 ulong
多一个可能的值,因此应该有一组两个值映射到 same ulong
值,这会引入一个误报 "true" 结果。
理论上,我可以想象 null 被合并为 default(ulong)
,但是我上面示例中的结果将是真实的,这将是一个错误的答案。正如我们所见,编译器不会犯这个错误 - 它会正确回答。
来自 MSDN:
Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following:
...
For the equality operators
== !=
a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool
. The lifted form is constructed by adding a single ?
modifier to each operand type. The lifted operator considers two null values equal, and a null value unequal to any non-null value. If both operands are non-null, the lifted operator unwraps the operands and applies the underlying operator to produce the bool
result.
您没有使用运算符:
bool ==(ulong left, ulong right)
您正在使用提升运算符:
bool ==(ulong? left, ulong? right)
此运算符采用两个 ulong?
参数,如果两者均为空,或者两者均为非空且具有相同的值,则 returns 为真。
您可能正在查看 Visual Studio,在这种情况下它确实让您感到困惑:
不要对此感到困惑——正如@mjwills 在评论中指出的那样,this is a known issue。
如果你这样写:
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()
returns 0
如果 b
为 null
,否则值为 b
。所以 M
returns true
当且仅当 b
不为空,并且与 a
.
具有相同的值
If we use the == operator between an expression of ulong and an
expression of ulong?, then the operator overload bool ulong(ulong
left, ulong right) is used.
问题的很大一部分是 Visual Studio 的智能感知错误地显示正在使用 ulong
的 ==
运算符(如果您将鼠标悬停在 ==
上)。
根据 https://github.com/dotnet/roslyn/issues/21494,这是一个错误。 实际上 使用该运算符。
由于您所有其他问题都是基于该错误前提,因此意识到该错误的存在会使其他问题基本消失。
如果我们在 ulong
表达式和 ulong?
表达式之间使用 ==
运算符,则似乎使用了运算符重载 bool ulong(ulong left, ulong right)
。
换句话说,运算符认为两个表达式都是非空的。
在此示例程序中,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;
}
}
- 这怎么能不扔呢?没有从值为 null 的
ulong?
到ulong
的转换。(ulong)(ulong?)null
抛出:"Nullable object must have a value." - 这个 return
ulong?
的每个可能值 的正确值是否正确,包括 null?如果是这样,如何?类型ulong?
比ulong
多一个可能的值,因此应该有一组两个值映射到 sameulong
值,这会引入一个误报 "true" 结果。
理论上,我可以想象 null 被合并为 default(ulong)
,但是我上面示例中的结果将是真实的,这将是一个错误的答案。正如我们所见,编译器不会犯这个错误 - 它会正确回答。
来自 MSDN:
Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following:
...
For the equality operators
== !=
a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is
bool
. The lifted form is constructed by adding a single?
modifier to each operand type. The lifted operator considers two null values equal, and a null value unequal to any non-null value. If both operands are non-null, the lifted operator unwraps the operands and applies the underlying operator to produce thebool
result.
您没有使用运算符:
bool ==(ulong left, ulong right)
您正在使用提升运算符:
bool ==(ulong? left, ulong? right)
此运算符采用两个 ulong?
参数,如果两者均为空,或者两者均为非空且具有相同的值,则 returns 为真。
您可能正在查看 Visual Studio,在这种情况下它确实让您感到困惑:
不要对此感到困惑——正如@mjwills 在评论中指出的那样,this is a known issue。
如果你这样写:
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()
returns 0
如果 b
为 null
,否则值为 b
。所以 M
returns true
当且仅当 b
不为空,并且与 a
.
If we use the == operator between an expression of ulong and an expression of ulong?, then the operator overload bool ulong(ulong left, ulong right) is used.
问题的很大一部分是 Visual Studio 的智能感知错误地显示正在使用 ulong
的 ==
运算符(如果您将鼠标悬停在 ==
上)。
根据 https://github.com/dotnet/roslyn/issues/21494,这是一个错误。 实际上 使用该运算符。
由于您所有其他问题都是基于该错误前提,因此意识到该错误的存在会使其他问题基本消失。