Why code inside common functions ignores overloaded operator ==

What is the workaround for this problem?

class Program { static void Main(string[] args) { var a = new Test(); var b = new Test(); var eq = Check(a, b); } private static bool Check<T>(T a, T b) where T : class { return a == b; //will not call overloaded == } } public class Test { public override bool Equals(object obj) { Test other = obj as Test; if (ReferenceEquals(other, null)) return false; return true; } public static bool operator ==(Test left, Test right) { return Equals(left, right); } public static bool operator !=(Test left, Test right) { return !(left == right); } } 
+4
source share
4 answers

The == operator is not used because your generic method exists regardless of the types that you will use for T He does not know that all types used as T will overload the == operator ... Instead, you can use the Equals method:

 private static bool Check<T>(T a, T b) where T : class { return Equals(a, b); } 
+8
source

The "solution" here is the challenge

  private static bool Check<T>(T a, T b) where T : class { //return a == b; // will not call overloaded == return a.Equals(b); // will cal overloaded Equals } 
+4
source

This is a known behavior. MSDN says:

When applying the where T : class constraint, it is recommended that you do not use the == and! = Operators for the type parameter, because these operators will only check the reference identifier, and not for equality of values . This is true even if these operators are overloaded with the type used as an argument.

To verify equality, you must implement IEqualityComparer (or directly call one of the Equal methods).

+3
source

The workaround is to call the virtual Equals method and override this:

 private static bool Check<T>(T a, T b) where T : class { return a.Equals(b); } 

The overloaded operator == allowed at compile time, so it is resolved to implement the System.Object operator. A virtual method call is dispatched at run time, so an override of System.Object.Equals (if any) is called.

In your code, a virtual Equals call occurs in an overloaded == method, which is not called; that why overriding Equals is not called.

Another solution, if you have control over the classes passed to the method, should be limited to IEquatable<T> and implement this in your classes:

 private static bool Check<T>(T a, T b) where T : class, IEquatable<T> { return a.Equals(b); } 

This will cause an overload for the Equals(T) method, which will save some type checking at runtime.

+2
source

Source: https://habr.com/ru/post/1402689/


All Articles