Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# &引用;ulong==ulong?“;评价为;ulong==ulong";工作正常_C#_Operator Overloading_Nullable_Equals Operator - Fatal编程技术网

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;
    }
}
  • 这怎么能不扔?没有从值为null的
    ulong?
    转换为
    ulong
    (ulong)(ulong?)null
    抛出:“可为null的对象必须有一个值。”
  • 这是否为
    ulong?
    的每个可能值返回正确的值,包括null?如果是,怎么做?类型
    ulong?
    ulong
    多了一个可能值,因此应该有一组两个值映射到相同的
    ulong
    值,这将引入一个假阳性“真”结果
  • 理论上,我可以想象null合并到
    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?
    ,该参数可用于解释所有问题。我不知道有什么人。谢谢你详尽的回答!