the book said:
Comparing Two Generic Type Variables with Each Other Comparing two variables of the same generic type is illegal if the generic type parameter is not known to be a reference type. private static void ComparingTwoGenericTypeVariables<T>(T o1, T o2) { if (o1 == o2) { } // Error } In this example, T is unconstrained, and whereas it is legal to compare two reference type vari- ables with one another, it is not legal to compare two value type variables with one another unless the value type overloads the == operator. If T were constrained to class , this code would compile, and the == operator would return true if the variables referred to the same object, checking for exact identity. Note that if T were constrained to a reference type that overloaded the operator == method, the compiler would emit calls to this method when it sees the == operator. Obviously, this whole discussion applies to uses of the != operator too.
try
void Main() { Test.test<B>(new B(), new B()); } // Define other methods and classes here class A { public static bool operator==(A x, A y) { return true; } public static bool operator!=(A x, A y) { return false; } } class B : A { public static bool operator==(B x, B y) { return false; } public static bool operator!=(B x, B y) { return true; } } class Test { public static void test<T>(T a, T b) where T : class { Console.WriteLine(a == b); } }
result:false
IL:
Test.test: IL_0000: nop IL_0001: ldarg.0 IL_0002: box 01 00 00 1B IL_0007: ldarg.1 IL_0008: box 01 00 00 1B IL_000D: ceq IL_000F: call System.Console.WriteLine IL_0014: nop IL_0015: ret
but
public static void test<T>(T a, T b) where T : A {
Test.test: IL_0000: nop IL_0001: ldarg.0 IL_0002: box 01 00 00 1B IL_0007: ldarg.1 IL_0008: box 01 00 00 1B IL_000D: call UserQuery+A.op_Equality IL_0012: call System.Console.WriteLine IL_0017: nop IL_0018: ret
时间: 2024-10-14 12:53:35