I have listed five different scenarios that I think the null-checking is necessary in the product code. Although, most of the reference books I have checked do NOT make such checkings. It is reasonable to ignore those checking while the original reference tries to deliver the other important ideas. Here, I summarize all my concerns as follows and please correct me if there are errors.
class Student
{
public string Name { get; set; }
public Student(string name)
{
Name = name;
}
public Student() { }
public override string ToString()
{
return string.Format("Name: {0}", Name);
}
}
class StudentNameComparer : IComparer<Student>
{
public int Compare(Student x, Student y)
{
if ( (x == null) || (y == null) ) // <C1> Should we check there?
throw new ArugmentNullException("bla bla");
return x.Name.CompareTo(y.Name);
}
}
////////////////////////////////////////////////////
List<Student> students = new List<Student> {
new Student("s1"),
new Student("s4"),
new Student("s3"),
new Student("s2")
};
students.Sort(delegate(Student x, Student y)
{
if ( (x == null) || (y == null) ) // <C2> Should we check there?
throw new ArugmentNullException("bla bla");
return x.Name.CompareTo(y.Name);
});
////////////////////////////////////////////////////
List<Student> students = new List<Student> {
new Student("s1"),
new Student("s4"),
new Student("s3"),
new Student("s2")
};
students.Sort( (x, y) =>
{
if ( (x == null) || (y == null) ) // <C3-1> Should we check there?
throw new ArugmentNullException("bla bla");
return x.Name.CompareTo(y.Name);
});
Or
students.Sort( (Student x, Student y) =>
{
if ( (x == null) || (y == null) ) // <C3-2> Should we check there?
throw new ArugmentNullException("bla bla");
return x.Name.CompareTo(y.Name);
});
////////////////////////////////////////////////////
List<Student> students = new List<Student> {
new Student("s1"),
new Student("s4"),
new Student("s3"),
new Student("s2")
};
foreach (Student std in students.OrderBy(p =>
{
if (p == null) // <C4> Should we check there?
{
throw new ArgumentNullException("...");
}
return p.Name;
}))
{
Console.WriteLine(std);
}
Well, just take a look at the interface in the documentation.
In fact, what is done there in the IComparer is wrong.
The preferred implementation is to use the CompareTo method of one of the parameters.
Comparing null with any type is allowed and does not generate an exception when using IComparable. When sorting, null is considered to be less than any other object.
So Compare() must not throw just because one of the elements is null.
Since we established that, the Sort method doesn't need the check, as we can see above that nulls sort just fine.
No idea on the last example, though. I believe throwing is a bit harsh in that case. However, nulls should probably not appear in your collections, anyway. If I have a list of students at least it doesn't make much sense to me to include nulls there.
Something like
p => p != null ? p.Name : string.Empty
could be used instead (which would be consistent with the ordering that is imposed by default on null values).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With