Using LINQ SequenceEqual extension method with occassionally null properties

I'm writing a simple console application that compares two instances of a custom class object. For each property, I'm writing True or False to the console window to show whether each of the objects' properties match.

Some properties, like ProductLines (List property), may be null in one or both objects... or neither. This presents a slight problem for using SequenceEqual, since it doesn't accept null values. Is there a better way to compare two sequence properties than the code I have written?

// test if either collection property is null.
if (commsA.Last().ProductLines == null || commsB.Last().ProductLines == null) 
{
    // if both null, return true.
    if (commsA.Last().ProductLines == null && commsB.Last().ProductLines == null)
    {
        Console.WriteLine("Property Match:{0}", true);
    }
    // else return false.
    else
    {
        Console.WriteLine("Property Match:{0}", false);
    }
}
// neither property is null. compare values and return boolean.
else
{
    Console.WriteLine("Property Match:{0}", 
          commsA.Last().ProductLines.SequenceEqual(commsB.Last().ProductLines));
}
Jon Skeet
people
quotationmark

I'd probably add a NullRespectingSequenceEqual extension method:

public static class MoreEnumerable
{
    public static bool NullRespectingSequenceEqual<T>(
        this IEnumerable<T> first, IEnumerable<T> second)
    {
        if (first == null && second == null)
        {
            return true;
        }
        if (first == null || second == null)
        {
            return false;
        }
        return first.SequenceEqual(second);
    }
}

Or using a stacked conditional operator:

public static class MoreEnumerable
{
    public static bool NullRespectingSequenceEqual<T>(
        this IEnumerable<T> first, IEnumerable<T> second)
    {
        return first == null && second == null ? true
             : first == null || second == null ? false
             : first.SequenceEqual(second);
    }
}

Then you can just use:

Console.WriteLine("Property Match: {0}",
     x.ProductLines.NullRespectingSequenceEqual(y.ProductLines));

(The business about whether or not you should call Last is slightly separate.)

You can reuse that extension method wherever you want, as if it were a normal part of LINQ to Objects. (It won't work for LINQ to SQL etc, of course.)

people

See more on this question at Stackoverflow