返回两个数中较大的一个,最简单的方法是什么?

3

假设我有一个实体,看起来像这样:

public class Album()
{
    public DateTime LastUpdated { get; set; }
    public List<Picture> Pictures { get; set; }
}

我要做的是创建一个LastActivity属性,用于返回最新活动的日期。对于Pictures集合而言,这很容易实现:
public DateTime LastActivity
{
    get { return Pictures.Max(x => x.LastUpdated); }
}

然而,我也希望考虑Album实体上的LastUpdated属性。我可以使用以下代码:

public DateTime LastActivity
{
    get { return Pictures.Max(x => x.LastUpdated) > this.LastUpdated
              ? Pictures.Max(x => x.LastUpdated)
              : this.LastUpdated) };
}

但这样做很糟糕,因为它将执行两次Max()转换。有没有更好的编写此代码的方法?

答案

这是我根据接受的答案提出的解决方案:

public virtual DateTime LastActivity
{
    get
    {
        var max = Pictures.Any() ? Pictures.Max(x => x.LastUpdated) : DateTime.MinValue;
        return max > this.LastUpdated ? max : this.LastUpdated;
    }
}

需要注意的是,如果您对一个空集合执行Max()操作,将会引发异常,因此您必须首先检查集合中是否有任何内容。


@mcl的解决方案比你的快大约35%。但令人惊讶的是,编译器无法优化上述调用。它实际上为每个Pictures.Max调用创建单独的委托...很奇怪。有时它可以进行优化,但有时却不能。在这种特殊情况下,我想知道为什么它不能... - user44298
9个回答

7

将最大值存储在一个变量中,而不是执行两次计算。

public DateTime LastActivity
{
    get 
    { 
        var max = Pictures.Max(x => x.LastUpdated);
        return max > this.LastUpdated
          ? max
          : this.LastUpdated 
    };
}

谢谢。我希望有一些.NET方法来处理它,但有时候天真的方法是最好的。 - Daniel T.

2
只需将图片日期分配给本地变量,然后进行您已经编写的比较即可。

1
public DateTime LastActivity
{
    get
    {
        var picturesMax = Pictures.Max(x => x.LastUpdated);
        return picturesMax > this.LastUpdated
          ? picturesMax
          : this.LastUpdated)
    };
}

1

这个怎么样?

public DateTime LastActivity 
{ 
    get 
    {
         DateTime lastPicture = Pictures.Max(x => x.LastUpdated);
         return lastPicture > this.LastUpdated ? lastPicture : this.LastUpdated;
     }
} 

1
public DateTime LastActivity
{         
    get { return Pictures.Select(x => x.LastUpdated).Concat(new DateTime[] { this.LastUpdated }).Max();
}

使用较新的C#符号,您可以将DateTime[]更改为[]以使其更加简洁。 - Mike

0

我在一个框架库中使用以下内容...

public static T Maximum<T>(params T[] values) 
    where T : struct, IComparable<T>
{
    var rV = values[0];
    foreach (var v in values.Where
        (v => v.CompareTo(rV) > 0))
        rV = v;
    return rV;
}

在客户端代码中,我可以简单地编写: var maxVal = lib.Maximum(Value1, Value2, .... , ValueN);

0

只需将最大值存储在一个临时变量中:

public DateTime LastActivity
{
    get {
        DateTime maxLastUpdated = Pictures.Max(x => x.LastUpdated);
        return maxLastUpdated > this.LastUpdated
            ? maxLastUpdated
            : this.LastUpdated) };
}

0

为了保持 LINQ 风格...

public DateTime LastActivity
{
    get 
    { 
         return Pictures.Any(x => x.LastUpdated > this.LastUpdated) 
                ? Pictures.Max(x => x.LastUpdated) 
                : this.LastUpdated; 
    }
}

更新:如果LINQ表达式没有返回结果,则添加默认的LastUpdated返回,并根据OP的评论进行了更正。

不幸的是,对于空集合的 Max() 操作将抛出异常而不是返回 null。 - Daniel T.

0

这很简单,应该可以轻松处理一个空的Pictures集合:

public DateTime LastActivity
{
    get
    {
        return Pictures.Aggregate(LastUpdated,
                            (a, x) => x.LastUpdated > a ? x.LastUpdated : a);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接