==演算子のリロードについて
2946 ワード
今日、コードを書くときに、クラスをカスタマイズして、2つのインスタンスを比較するときに便利にするために==演算子を再ロードしました.もちろん、同じように再ロードしました!=演算子.テスト中にstack overflowの問題が発生しました.
コードは以下の通りです(もちろん本物のコードではありませんが、問題を説明できます):
Mainメソッドは次のとおりです.
コードを実行すると直接死んでしまうことがわかり、debugはstack overflowであることがわかります.コードをよく見て、死ぬのは理にかなっている...
==演算子がリロードされているのでif(a==null&&b==null)を判断する際に、リロード後演算子の論理を使用し、a==nullを判断してから行きます.死ぬまで循環する.
仕方なく、本を开けてみると、本には重载==の例がありますが、nullかどうかは判断されていません.それからGoogleに行って、私は関連する文章があるべきだと思いますが、キーワードの検索が間違っているかもしれません.いつも欲しいものが見つかりません.次に、if(a==null)という方法でオブジェクトが空いているかどうかを判断する必要がない方法を探してみましたが、残念ながら見つかりませんでしたが、ある海外のフォーラムで外国人が人の質問に答えているのを見たとき、if(this.Equals(null){...}という行を残しました.
よく考えてみると、Stringクラスは==演算子のリロードを実現しているようで、reflectorを開いてソースコードを見てみました.コードは以下の通りです.
Equalsメソッドのコードは次のとおりです.
間違っているように見えますがnull判断もしたでしょう.いずれにしても、引っ越してからにして、運行すると、やはり--やはりだめです...私のコードが分からなかったのか、それとも.NetはStringに特殊な処理をしたが、どうせ役に立たなかった.
最後に同僚に手伝ってもらったが、仕方がなかったが、先日書いたコードについて話していたときに少し考えてくれたので、別の方法で相手がnullかどうかを判断した.
オブジェクトが空かどうかをa is objectで判断します.すべてのオブジェクトがobjectクラスから直接または間接的に継承され、nullは自然にこの列に含まれないため、aがnullの場合、a is objectは自然にfalseを返し、他の場合はtrueを返します.
Mainメソッドを再実行して、うーん、やっと欲しい結果が得られました.
コードは以下の通りです(もちろん本物のコードではありませんが、問題を説明できます):
public class Dog
{
private string name;
public Dog(string dogName)
{
this.name = dogName;
}
// ,
public static bool operator == (Dog a, Dog b)
{
if (a == null && b == null) return true; // if (dog == null)
if (a == null || b == null) return false;
return a.name == b.name;
}
public static bool operator != (Dog a, Dog b)
{
return !(a == b);
}
public override bool Equals(object obj)
{
Dog dog = obj as Dog;
if (dog == null) return false;
return this.name == dog.name;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
Mainメソッドは次のとおりです.
public static void Main()
{
Dog wangcaiA = new Dog(" ");
Dog wangcaiB = new Dog(" ");
Dog laifu = new Dog(" ");
Dog nullDog = null;
Console.WriteLine("wangcaiA == wangcaiB : " + (wangcaiA == wangcaiB));
Console.WriteLine("wangcaiA == laifu : " + (wangcaiA == laifu));
Console.WriteLine("wangcaiA == nullDog : " + (wangcaiA == nullDog));
Console.WriteLine("nullDog == nullDog : " + (nullDog == nullDog));
}
コードを実行すると直接死んでしまうことがわかり、debugはstack overflowであることがわかります.コードをよく見て、死ぬのは理にかなっている...
==演算子がリロードされているのでif(a==null&&b==null)を判断する際に、リロード後演算子の論理を使用し、a==nullを判断してから行きます.死ぬまで循環する.
仕方なく、本を开けてみると、本には重载==の例がありますが、nullかどうかは判断されていません.それからGoogleに行って、私は関連する文章があるべきだと思いますが、キーワードの検索が間違っているかもしれません.いつも欲しいものが見つかりません.次に、if(a==null)という方法でオブジェクトが空いているかどうかを判断する必要がない方法を探してみましたが、残念ながら見つかりませんでしたが、ある海外のフォーラムで外国人が人の質問に答えているのを見たとき、if(this.Equals(null){...}という行を残しました.
よく考えてみると、Stringクラスは==演算子のリロードを実現しているようで、reflectorを開いてソースコードを見てみました.コードは以下の通りです.
public static bool operator ==(string a, string b)
{
return Equals(a, b);
}
public static bool operator !=(string a, string b)
{
return !Equals(a, b);
}
Equalsメソッドのコードは次のとおりです.
public static bool Equals(string a, string b)
{
return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b)));
}
間違っているように見えますがnull判断もしたでしょう.いずれにしても、引っ越してからにして、運行すると、やはり--やはりだめです...私のコードが分からなかったのか、それとも.NetはStringに特殊な処理をしたが、どうせ役に立たなかった.
最後に同僚に手伝ってもらったが、仕方がなかったが、先日書いたコードについて話していたときに少し考えてくれたので、別の方法で相手がnullかどうかを判断した.
public static bool operator == (Dog a, Dog b)
{
bool aIsNull = !(a is object);
bool bIsNull = !(b is object);
if (aIsNull && bIsNull) return true;
if (aIsNull || bIsNull) return false;
return a.name == b.name;
}
オブジェクトが空かどうかをa is objectで判断します.すべてのオブジェクトがobjectクラスから直接または間接的に継承され、nullは自然にこの列に含まれないため、aがnullの場合、a is objectは自然にfalseを返し、他の場合はtrueを返します.
Mainメソッドを再実行して、うーん、やっと欲しい結果が得られました.