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.
phoog source share