C#Elvis Operator可为空的布尔值

时间:2018-10-24 12:30:44

标签: c# .net boolean operators

如何向Elvis Operator申请以下内容:

Exp: b= a?.attr> 0

结果应为:如果anull,则b应该是null,否则,b应该是{{1}的结果}。

2 个答案:

答案 0 :(得分:4)

正如其他人在现在删除的答案中指出的那样,您遇到的问题是由于可疑的设计决策。 “提升”运算符是采用空值的普通运算符的版本,如果操作数为null,则生成null,否则生成常规运算符的可空版本。例如,加法运算符为解除运算符:

int? a = 111;
int? b = null;
int? c = a + a; // 222, but nullable
int? d = a + b; // null

您遇到的问题是C#中的比较运算符没有遵循其他提升运算符的格式。在C#中,比较运算符为:

  • ==如果两个操作数都为null,则为true;如果恰好一个操作数为null,则为false;否则,将产生非提升式相等性

  • !===

  • 相反 如果任何一个操作数为null,则
  • <><=>=产生false,否则进行常规比较。请注意,这意味着x == y可以为true,x >= y可以为false,这意味着>=与“大于或等于”的含义不同。

    < / li>

这是一团糟,您应该对此感到困惑。

您可能要做的就是编写一个具有所需语义的方法:

static bool? LiftedLessThan(int? x, int? y) => 
  (x == null | y == null) ? (bool?)null : x.Value < y.Value;

(请注意,强制转换必须使C#类型系统满意,这要求结果的结果和条件的替代都必须具有一致的类型。)

现在您的程序片段是:

bool? b = LiftedLessThan(a?.attr, 0);

看起来不太好,但是可以用。

答案 1 :(得分:0)

根据我的理解,您希望使用ternary operator在一个单行中进行以下操作:

if(A==null){
    B=null;
}
else{
    B= A.Attr > 0
}

默认情况下,您只需将B分配为null:

bool? B = null;
if(A==null){
    B= A.Attr > 0
}

或正如德米特里·拜琴科(Dmitry Bychenko)所说:

 B = a == null ? (bool?)null : a.Attr > 0;

请您确认您的预期结果是:

  

A不为空,A.Attr = 0 => B =假
  A不为空,A.Attr = 2 => B = True
  A不为空,A.Attr = -1 => B = False
  A为空,A.Attr =为空=> B =为空

public class A { public int Attr; }
private static void SO_52969048()
{
    bool? B ;
    var inputs = new List<A> {
        new A{ Attr = 0},
        new A{ Attr = 2},
        new A{ Attr = -1},
        null
    };

    foreach (var a in inputs)
    {
        B = a == null ? (bool?)null : a.Attr > 0;
        Console.WriteLine($" A  {(a == null ? "is null" : "is not null")}, A.Attr = {(a == null ? "is null" : a.Attr.ToString())} => B= {(B == null ? "is null" : B.ToString())}");
    }
}