だから私はあなたのコメントに応えて別の答えを投稿しています:
「ノードがnullであることを確認しましたが、そうではありません。」
それが本当なら、ここにいくつかの他のオプションがあります。
node.previous
クラス/構造体の定義を見てください。==
nullと比較するとエラーをスローするCUSTOM演算子を実装できます。Nullable<T>
例として、タイプについて考えてみましょう。HasValueプロパティがfalseの場合にtrueを返すオーバーロードされた==
演算子があります(明らかに、これは構造体であるため、真にnullではありませんが、演算子をオーバーロードすると目的の動作が得られます)。これを修正するには、どちらが実行object.ReferenceEquals(node.previous, null)
されないかをテストできます。オーバーロードされます。定義を変更するためのアクセス権がある場合はnode.previous
、おそらく、nullと比較したときにオーバーロードされた演算子が例外をスローする理由を見つけることができます(明らかにすべきではありません)
nodes
nullの可能性があります。その場合、エラーをスローしているのはforeachステートメントです。nodes == null
foreachの前にテストします。
- - - - - - - -編集 - - - - - - - -
Jeppeが指摘したように、(上記のオプション#1での)私のアナロジーは誤解Nullable<T>
を招く可能性があります(実際、ポイント自体は正しいものの、議論を混乱させました)。演算子をオーバーライドするという考えをよりよく説明するために==
、タイプを示す例を以下に投稿しましたContainer
。この型は構造体であるため、それ自体がnullになることはありませんが、単一のValueオブジェクトが含まれています。(この構造体のポイントはContainer
、含まれているオブジェクトがnullであっても、nullであるかどうかを気にせずに任意のオブジェクトを操作できることですValue
)。==
注意すべき主な点は、コンテナをnullと比較した場合、結果はisの場合は真になり、がの場合Value
は真null
ではないということです。==
演算子はオーバーライドされませんでした(構造体が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である場合を処理する必要があることを除いて、構造体に似ています。この場合、オーバーライドの別の驚くべき結果があることに注意してください==
。==
2つの参照型は、異なるオブジェクトを参照している場合でも、プロパティが等しい限り、互いに等しく()にすることができ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 ==)