MSCLR2.0 の Single.Equals() のオーバーロード
Equals および等値演算子 (==) 実装のガイドライン
Equals メソッドの実装
これらのガイドラインを破りまくることにもなるし。。。
まず、上記2項が対象としている Equals は、各クラスがスペシャライズした独自の Equals のオーバーロードにまで影響してるかどうか? という解釈の問題がありそうです。
特に、後者の文章では
指定した型で IComparable インターフェイスを実装する場合は、その型で Equals をオーバーライドします。
という文章があります。一瞬、.NET 2.0 が色々でまわってきているので、パラメタライズドタイプ?とか勘違いしそうですが、これは、IClonable などの実装でよくみられる
public int CompareTo(MyClass obj) { return ...; } int IComparable.CompareTo(object obj) { MyClass that = obj as MyClass; if (that == null) throw new ArgumentException("obj"); return this.CompareTo(that); }
みたいなことを言ってるのであって、今回の話とは深く関係はないかと思います。
個人的には、Equals にかかっている対象性やらなんやらの問題は、object として扱ったときの抽象的な動作の定義について書かれているのであって、個々のクラス固有の Single.Equals(int) などには影響していないと考えます。
1つは、Single.Equals(int) のような実装は、対象性などの要素が重要になる Hashtable のキーとして登録するときの比較メソッド呼び出しとは基本的に無縁であるという点があげられます。*1
あくまで、それは何らかのインターフェスや、個々の型が定義する Equals() という同じ名前のメソッドのオーバーロードであって、オーバーライドではないのです。
Single.Equals(int) が Single の保持する値が整数の場合に true を返せるのは、使う側からすればかなり自然なことで、影響があるコードは存在するかもしれませんが、問題ないレベルかと思います。逆に、この変更でケアレスミスが救われてコードを書いた人の期待通りに動作するようになるほうが多いぐらいではないでしょうか(笑)
そういや
static MyClass() { fooBarTable = new Hashtable(); fooBarTable[ 0 ] = ...; fooBarTable[ 1 ] = ...; fooBarTable[ 2 ] = ...; fooBarTable[ 3 ] = ...; } public xxx FindTable(short key) { if (fooBarTable.Contains(key)) { return fooBarTable[key] as xxx; } else { throw new ArgumentOutOfRange("key"); } }
とか、1回はやるよね? ね?(汗
これで Int16.Equals() と Int32.Equals() とどっちが呼ばれるか忘れました*2が、どっちが呼ばれるにしても false しか返さないので、このテーブルはひけません、と(笑