因此,我发布了另一个答案以回应您的评论:
“我已经检查过 node 是否为空,在任何时候都不是。”
如果这是真的,这里还有其他一些选择;
看一下node.previous
类/结构定义。它可以实现一个 CUSTOM==
运算符,与 null 相比会引发错误。例如,考虑Nullable<T>
类型。它有一个重载的==
运算符,如果 HasValue 属性为 false,则返回 true (显然,由于它是一个结构,它不是真正的 null,但重载运算符会给出所需的行为。)要解决这个问题,您可以测试object.ReferenceEquals(node.previous, null)
哪个不会被超载。如果您有权更改node.previous
定义,也许您可以找出为什么重载运算符与 null 相比会引发异常(显然不应该)
nodes
可能为 null,在这种情况下,引发错误的是 foreach 语句。nodes == null
在 foreach 之前进行测试。
- - - - - - - -编辑 - - - - - - - -
正如Jeppe指出的那样,我与Nullable<T>
(在上面的选项 #1 中)的类比可能会产生误导(实际上它确实混淆了讨论,尽管这一点本身是正确的)。为了更好地说明重写==
运算符的想法,我在下面发布了一个示例来演示该Container
类型。这种类型是一个结构,所以它本身永远不能为空,但它包含一个值对象。(这个结构的要点是你可以使用任何Container
对象而不用担心它是否为空,即使包含的Value
对象可能是空的)。主要需要注意的是,当将 Container 与==
null 进行比较时,如果Value
is则结果将为 true 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
以防万一您想知道覆盖==
将如何影响一个类,我在下面编写了另一个示例来演示一个Box
类。它类似于Container
结构,除了我们必须处理 Box 对象本身为 null 的情况。请注意,在这种情况下,覆盖还有另一个令人惊讶的结果==
。两个引用类型可以彼此相等 ( ==
),即使它们引用不同的对象,只要它们具有相等的Value
属性。
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 ==)