So I'm posting another answer in response to your comment:
"I have checked for node being null, it isn't, at any point."
If that IS true, there here are some other options;
Take a look at the node.previous
class/struct definition. It COULD implement a CUSTOM ==
operator that throws an error when compared to null. As an example, think about the Nullable<T>
type. It has an overloaded ==
operator that returns true if the HasValue property is false (obviously, since it is a struct it isn't truly null, but overloading the operator gives the desired behavior.) To fix this, you could test object.ReferenceEquals(node.previous, null)
which wouldn't be overloaded. If you have access to change the node.previous
definition, perhaps you can find out why the overloaded operator throws an exception when compared to null (which it obviously shouldn't)
nodes
could be null, in which case it is the foreach statement that is throwing the error. Test nodes == null
before the foreach.
---------------Edit---------------
As Jeppe pointed out, my analogy with Nullable<T>
(in option #1, above) could be misleading (in fact it did confuse the discussion, although the point itself was correct). In order to better illustrate the idea of overriding the ==
operator, I've posted an example below that demonstrates the Container
type. This type is a struct, so it can never be null itself, but it contains a single Value object.
(The point of this struct is that you can work with any Container
object without worrying whether or not it is null, even though the contained Value
object might be null). The main thing to note is that when a Container is compared with ==
to null, the result will be true if Value
is null
, which would NOT be true if the ==
operator weren't overridden (because a struct can never be null).
public struct Container {
public object Value { get; set; }
public bool IsNull { get { return Value == null; } }
public static bool operator ==(Container x, object y) { return x.Equals(y); }
public static bool operator !=(Container x, object y) { return !x.Equals(y); }
public override bool Equals(object obj) {
if (obj is Container)
return Value == ((Container)obj).Value;
return Value == obj;
}
public override int GetHashCode() { return Value == null ? 0 : Value.GetHashCode(); }
}
////---------Test----------
var x = new Container { Value = null };
var y = new Container { Value = "hi" };
var z = new Container { Value = null };
Print(x == null); //true
Print(x == y); //false
Print(x == z); //true
And just in case you are wondering how overriding ==
would affect a class, I've written another example below that demonstrates a Box
class. It's similar to the Container
struct, except that we have to deal with the case in which the Box object is null itself. Note that in this case, there is another surprising result of overriding ==
. Two reference types can be equal (==
) to each other, even if they reference different objects, as long as they have equal Value
properties.
public class Box {
public static bool ItemsEqual(object x, object y) {
object xval, yval;
xval = x is Box ? (x as Box).Value : x;
yval = y is Box ? (y as Box).Value : y;
return xval == yval;
}
public object Value { get; set; }
public bool IsNull { get { return Value == null; } }
public static bool operator ==(Box x, object y) { return ItemsEqual(x, y); }
public static bool operator !=(Box x, object y) { return !ItemsEqual(x, y); }
public override bool Equals(object obj) { return ItemsEqual(this, obj); }
public override int GetHashCode() { return Value == null ? 0 : Value.GetHashCode(); }
}
////---------Test----------
object n = null;
Box w = null;
Box x = new Box { Value = null };
Box y = new Box { Value = "hi" };
Box z = new Box { Value = "hi" };
Print(w == null); //true (uses overridden '==' because w is defined as a Box)
Print(w == n); //true
Print(x == w); //true
Print(x == null); //true
Print(x == n); //true
Print(w == y); //false
Print(x == y); //false
Print(y == z); //true (actual ref's differ, but values are ==)