取两个可以为空的值

时间:2015-05-01 10:14:10

标签: c# nullable

假设我有两个可为空的整数:

int? a = 10;
int? b = 20;

我想获取最大的非null值,这样如果两个值都为null,则结果为null。

我可以写一些冗长的东西,例如:

int? max;
if (a == null)
{
    max = b;
}
else if (b == null)
{
    max = a;
}
else
{
    max = a > b ? a : b;
}

对于我的喜好,这感觉有点太笨重(并且可能容易出错)。返回更大值的最简单方法是什么,这也是空值的可能性?

10 个答案:

答案 0 :(得分:71)

使用空合并运算符的一行:

int? c = a > b ? a : b ?? a;

答案 1 :(得分:62)

这适用于任何可空的:

Nullable.Compare(a, b) > 0? a: b;

答案 2 :(得分:58)

这些行用一个小技巧显示了必要的逻辑:

if (a == null) return b; // handles b== null also
if (b == null) return a;
// now a!=null, b!=null
return Math.Max(a.Value, b.Value);

或使用?:(完全相同的逻辑)

在一行中
 return a == null ? b : b == null ? a : Math.Max(a.Value, b.Value);

<小时/> 的修改

虽然上面的答案对于教育目的很有意思,但是解决此问题的推荐方法。推荐的方法是不重新发明轮子而是找到匹配的轮子:

正如@roman指出的那样,存在一种Nullable.Compare()方法,使其更具可读性:

return Nullable.Compare(a, b) > 0 ? a : b;

答案 3 :(得分:41)

这是Null coalescing operator ??的好地方 如果值不是null,则返回第一个值,否则返回第二个值。

int? c = a > b ? a : b ?? a;

Proof here

如果值为false,则使用比较运算符将返回null的事实,表达式将为您提供所需的结果:

a        | b        || a>b | a   | b??a | a>b ? a : b??a
--------------------||----------------------------------
> b      | NOT NULL ||  T  | a   | --   | a
≤ b      | NOT NULL ||  F  | --  | b    | b
NOT NULL | NULL     ||  F  | --  | a    | a
NULL     | NOT NULL ||  F  | --  | b    | b
NULL     | NULL     ||  F  | --  | NULL | NULL

答案 4 :(得分:20)

简短版本是:

var result = new[] { a, b }.Max();

答案 5 :(得分:8)

这个怎么样

 private int? Greater(int? a, int? b)
 {
   if(a.HasValue && b.HasValue)
    return a > b ? a : b;

   if(a.HasValue)
     return a;
   if(b.HasValue)
     return b;

   return null;
  }

或更简洁:

 private int? Greater(int? a, int? b)
 {
   if(a.HasValue && b.HasValue)
    return a > b ? a : b;

   return a.HasValue ? a : b;
  }

答案 6 :(得分:4)

!b.HasValue || a > b ? a : b

如果b为空(!b.HasValue),则a始终是正确答案。

如果b不为空但a为空,则a > b将为false,b将为正确答案。

否则它与非可空整数相同a > b ? a : b

答案 7 :(得分:4)

如何使方法能够处理尽可能多的可空值:

public static int? GetLargestNonNull(params int?[] values)
{
    IEnumerable<int?> nonNullValues = values.Where(v => v.HasValue);

    if (nonNullValues.Any())
    {
        return nonNullValues.Select(v => v.Value).Max();
    }

    return null;
}

并使用如下:

int? result = GetLargestNonNull(a, b);

除此之外还能够处理:

int? result = GetLargestNonNull(a, b, c, d, e, f);

或者,如果您使用的是从其他来源收到的值,则可以更改方法参数以接受列表。

答案 8 :(得分:0)

我想补充一点,这里的单线解决方案很好。但是要揭秘代码,在 null合并运算符

附近添加一个括号
private int? Max(int? a, int? b)
{
    return a > b ? a : (b ?? a);
    //returns a if bigger else non null prefering b
}

如果它更大则返回a,否则返回b ?? a - 返回非null(如果两者都为null则返回null)更喜欢b

答案 9 :(得分:0)

这是一个非常直观和可读的解决方案。这适用于任何数量的值以及任何可以为null的结构,例如say,int?还是DateTime?

此外,如果所有值都为null,则返回null。

  public static T? GreatestOrDefault<T>(this IEnumerable<T?> values) where T : struct
        {
            var any = values.Any(a => a.HasValue);

            if (!any) return null;

            var firstOrDefault = values.Where(v => v.HasValue).Max();

            return firstOrDefault;
        }

或者您可能想要执行以下操作:

<div class="container-fluid fill">
<app-navbar></app-navbar>
<div class="container fill">
  <div class="row padding">
    <div class="col-md-3 ">
      <app-sidebar></app-sidebar>
    </div>
    <div class="col-md-6 text-center">
     <app-menu-section></app-menu-section>
    </div>
    <div class="col-md-3 ">
     <app-cart></app-cart>
    </div>
  </div>
</div>
</div>