Reputation: 38400
Let's say I have an entity that looks like this:
public class Album()
{
public DateTime LastUpdated { get; set; }
public List<Picture> Pictures { get; set; }
}
What I want to do is create a LastActivity
property that will return the latest date of the activity. This is easy enough for the Pictures
collection:
public DateTime LastActivity
{
get { return Pictures.Max(x => x.LastUpdated); }
}
However, I also want to consider the LastUpdated
property on the Album
entity as well. I could use this code:
public DateTime LastActivity
{
get { return Pictures.Max(x => x.LastUpdated) > this.LastUpdated
? Pictures.Max(x => x.LastUpdated)
: this.LastUpdated) };
}
But this is bad because it will do the Max()
transformation twice. Is there a better way of writing this code?
This is the solution I came up with, based on the accepted answer:
public virtual DateTime LastActivity
{
get
{
var max = Pictures.Any() ? Pictures.Max(x => x.LastUpdated) : DateTime.MinValue;
return max > this.LastUpdated ? max : this.LastUpdated;
}
}
The thing to watch out for is that if you do a Max()
on an empty collection, you'll get an exception, so you have to check to see if there's anything in the collection first.
Upvotes: 3
Views: 5383
Reputation: 269398
This is fairly straightforward and should take an empty Pictures
collection in its stride:
public DateTime LastActivity
{
get
{
return Pictures.Aggregate(LastUpdated,
(a, x) => x.LastUpdated > a ? x.LastUpdated : a);
}
}
Upvotes: 0
Reputation: 16708
To keep it LINQy...
public DateTime LastActivity
{
get
{
return Pictures.Any(x => x.LastUpdated > this.LastUpdated)
? Pictures.Max(x => x.LastUpdated)
: this.LastUpdated;
}
}
Update(s): added the default LastUpdated to be returned if the LINQ expression returns no results, and corrected for the OP's comment.
Upvotes: 0
Reputation: 9298
Just store the max in a variable rather that performing the calculation twice.
public DateTime LastActivity
{
get
{
var max = Pictures.Max(x => x.LastUpdated);
return max > this.LastUpdated
? max
: this.LastUpdated
};
}
Upvotes: 7
Reputation: 47048
public DateTime LastActivity
{
get { return Pictures.Select(x => x.LastUpdated).Concat(new DateTime[] { this.LastUpdated }).Max();
}
Upvotes: 1
Reputation: 46193
Just store the max value in a temporary:
public DateTime LastActivity
{
get {
DateTime maxLastUpdated = Pictures.Max(x => x.LastUpdated);
return maxLastUpdated > this.LastUpdated
? maxLastUpdated
: this.LastUpdated) };
}
Upvotes: 0
Reputation: 59463
How about this?
public DateTime LastActivity
{
get
{
DateTime lastPicture = Pictures.Max(x => x.LastUpdated);
return lastPicture > this.LastUpdated ? lastPicture : this.LastUpdated;
}
}
Upvotes: 1
Reputation: 6734
public DateTime LastActivity
{
get
{
var picturesMax = Pictures.Max(x => x.LastUpdated);
return picturesMax > this.LastUpdated
? picturesMax
: this.LastUpdated)
};
}
Upvotes: 1
Reputation: 146499
I use the following in a framework library...
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;
}
In client code I can simply write
var maxVal = lib.Maximum(Value1, Value2, .... , ValueN);
Upvotes: 0
Reputation: 56660
Just assign the picture dates maximum to a local variable and then do the comparison you've already written.
Upvotes: 2