Take the maximum value and nullcollection from the Collection of complex classes containing null values.
In routine programming, we often encounter comparing, obtaining the maximum or minimum values in a Collection of complex classes.
For the simplest example, we need to select the element containing the maximum value in a collection of the following structures:
public class Class<T> where T : struct{ public T? Value { get; set; }}
var ints = new List<Class<int>>(){ new Class<int>() { Value = 2 }, new Class<int>() { Value = 10 }, new Class<int>() { Value = 5 }, new Class<int>() { Value = 10 },};
If you do not use the. Net advanced features, it is usually as follows:
var max = new Class<int>() { Value = Int32.MinValue };foreach (var i in ints){ if (i.Value != null && i.Value > max.Value) { max = i; }}return max;
In addition to tedious and tasteless writing, there is also an obvious Bug. Although it cannot be exposed in the above example, it is assumed that the set does not have one element, or the composition is as follows:
var ints = new List<Class<int>>(){ new Class<int>() { Value = null }, new Class<int>() { Value = null }, new Class<int>() { Value = null },};
At this moment, we want to return an element that contains a null value, and the above method will bring us an element that contains the minimum Int32 value, which is not in the ints set!
You will want to use the Max () of the Linq framework, for example:
var max = ints.Max(i => i.Value);
But in fact, this method can only return the Value member variable of the element, that is, int? Type, so this is not what we want.
At this moment, the correct method may be:
var max = ints.First(i => i.Value == ints.Max(j => j.Value));
However, this still has the opportunity to throw an exception. Suppose the set is as follows:
var ints = new List<Class<int>>(){ new Class<int>() { Value = null }, new Class<int>() { Value = null }, new Class<int>() { Value = null }, null};
In this set, we add a real null element (instead of an element containing a null value), and ints. Max () will throw NullReferenceException.
To solve this problem, we can rewrite the max statement:
var max = ints.First(i => i.Value == ints.Max(j => { return j == null ? null : j.Value; }));
You may have noticed that the Max () method adds null value judgment, but it is not required in the First () method. Do not rush to complain that the collection methods designed by Microsoft are inconsistent.
As for why, I will hand over this assignment to you. First, I will explore the answer in the link below. :)
Http://referencesource.microsoft.com/
(This website was built by Microsoft two years ago to facilitate software engineers to view. Net source code)