error? in CLR via c#

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  

 

原文地址:https://www.cnblogs.com/xray/p/5732219.html