using System; public class Test { // コンパイルエラー。whereなしではジェネリック型に演算子を適用できない。 //static void f(T x, T y) { // Console.WriteLine(x == y ? "OK" : "NG"); //} // where で参照型だけに制限すれば演算子が使えるが、object.== が呼ばれる static void f(T x, T y) where T: class { Console.WriteLine(x == y ? "OK" : "NG"); Console.WriteLine("変数の型:" + typeof(T).Name + " / 値の型:" + x.GetType().Name); } // 明示的に ClassA に制約すれば、そのクラスの == が呼ばれる static void g(T x, T y) where T: ClassA { Console.WriteLine(x == y ? "OK" : "NG"); Console.WriteLine("変数の型:" + typeof(T).Name + " / 値の型:" + x.GetType().Name); } // dynamic を使う場合 static void h(dynamic x, dynamic y) { Console.WriteLine(x == y ? "OK" : "NG"); Console.WriteLine("値の型:" + x.GetType().Name); } // 普通は演算子を使わずに object.Equals() を使うべき static void f1(object x, object y) { Console.WriteLine(object.Equals(x, y) ? "OK" : "NG"); Console.WriteLine("値の型:" + x.GetType().Name); } static void Main(string[] args) { var x = new ClassA(1); var y = new ClassA(1); f(x, y); // NG <= objectクラスの == を呼ぶようコンパイルされるため g(x, y); // OK h(x, y); // OK f1(x, y); // OK } class ClassA { public int Value1 { get; protected set; } // コンストラクタ public ClassA(int val) { Value1 = val; } // Equals()をオーバーライド public override bool Equals(object other) { Console.WriteLine("ClassA の Equals が呼ばれました。"); var other1 = other as ClassA; if (object.ReferenceEquals(other1, null)) return false; return object.Equals(this.Value1, other1.Value1); } // Equals() が True になる場合は GetHashCode() も同じ値を返す必要がある public override int GetHashCode() { return Value1.GetHashCode(); } // == 演算子を定義 public static bool operator==(ClassA self, ClassA other) { Console.WriteLine("ClassA の == が呼ばれました。"); return object.Equals(self.Value1, other.Value1); } // == を定義するためには != もペアで定義が必要 public static bool operator!=(ClassA self, ClassA other) { return !(self == other); } } }