Object.ReferenceEquals or == operator?

Why is ThrowIfNull implemented as:

  static void ThrowIfNull<T>(this T argument, string name) where T : class { if (argument == null) { throw new ArgumentNullException(name); } } 

Wouldn't it be better to rewrite it as:

  static void ThrowIfNull<T>(this T argument, string name) where T : class { if (object.ReferenceEquals(argument, null)) { throw new ArgumentNullException(name); } } 

Pros: It helps to avoid overloading Equals overloads and probably makes the code more understandable.

Any downsides to this? There must be some.

+6
source share
3 answers

There is no difference between them. You are confused by overriding Equals (which is not called in any of the implementations) with overload == (which will not be relevant in any fragment, since overloading is performed during compilation, and the compiler does not know enough about T to use any specific overload) .

Just to show what I mean:

 static void ThrowIfFoo<T>(this T argument, string name) where T : class { if (argument == "foo") { throw new Exception("You passed in foo!"); } } 

Testing with:

 "foo".ThrowIfFoo(); // Throws string x = "f"; x += "oo"; // Ensure it actually a different reference x.ThrowIfFoo(); // Doesn't throw 

ThrowIfFoo does not know that T will be a string - because it depends on the calling code - and overload resolution is only performed when ThrowIfFoo compiled. Therefore, it uses the operator ==(object, object) , and not ==(string, string) .

In other words, it is like this:

 object foo1 = "foo"; string tmp = "f"; object foo2 = tmp + "oo"; Console.WriteLine(foo1.Equals(foo2)); // Prints True Console.WriteLine(foo1 == foo2); // Prints false Console.WriteLine((string) foo1 == (string) foo2); // Prints True 

On the last line, the compiler knows that it can use the == overload because both operands have string time types.

+12
source

The == operator is allowed at compile time, not at run time, and since T is generic, the compiler will use the == implementation provided by the object itself, which checks for reference equality.

This is exactly what object.ReferenceEquals : does: the == implementation provided by object .

+5
source

This is mainly cosmetics.

obj == null will do a check and return, so there will be Equals if the argument is null and it is not overridden in T This would require a pretty winning / malicious implementation to return true when one argument is null.

+1
source

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


All Articles