2つのボックス化された整数(符号付きまたは符号なしのどちらでもかまいません)を比較して、等しいかどうかを疑問に思います。
たとえば、次のシナリオを見てください。
// case #1
object int1 = (int)50505;
object int2 = (int)50505;
bool success12 = int1.Equals(int2); // this is true. (pass)
// case #2
int int3 = (int)50505;
ushort int4 = (ushort)50505;
bool success34 = int3.Equals(int4); // this is also true. (pass)
// case #3
object int5 = (int)50505;
object int6 = (ushort)50505;
bool success56 = int5.Equals(int6); // this is false. (fail)
この方法でボックス化整数型を確実に比較する方法に困惑しています。実行時までそれらが何であるかはわかりません。また、long
の可能性があるため、両方をulong
にキャストすることはできません。また、どちらか一方が負の値になる可能性があるため、両方をulong
に変換することもできません。
私が思いつくことができる最良のアイデアは、一般的なタイプが見つかるか、それらが等しくないことを除外できるまで、試行錯誤を繰り返してキャストすることです。これは理想的なソリューションではありません。
ケース2では、ushort
は暗黙的にint
に変換できるため、実際にはint.Equals(int)
を呼び出すことになります。このオーバーロードの解決はコンパイル時に実行されます。コンパイラは_int5
_と_int6
_のタイプをobject
としてしか認識しないため、object.Equals(object)
...を呼び出すため、ケース3では使用できません。 2つのオブジェクトのタイプが異なる場合、_object.Equals
_はfalse
を返します。
あなたcould動的型付けを使用して、実行時に同じ種類のオーバーロード解決を実行しますが、次のようなことを試みた場合でも問題が発生します。
_dynamic x = 10;
dynamic y = (long) 10;
Console.WriteLine(x.Equals(y)); // False
_
ここでは、long
を処理するオーバーロードがないため、通常の_object.Equals
_を呼び出します。
1つのオプションは、値をdecimal
に変換することです。
_object x = (int) 10;
object y = (long) 10;
decimal xd = Convert.ToDecimal(x);
decimal yd = Convert.ToDecimal(y);
Console.WriteLine(xd == yd);
_
これは、ulong
とlong
の比較も処理します。
すべてのプリミティブ整数型のすべての値を正確に表すことができるため、decimal
を選択しました。