简体   繁体   中英

C# Type Comparison: Type.Equals vs operator ==

ReSharper suggests that the following be changed from:

Type foo = typeof( Foo );
Type bar = typeof( Bar );

if( foo.Equals( bar ) ) { ... }

To:

if( foo == bar ) { ... }

operator ==

// Summary:
//     Indicates whether two System.Type objects are equal.
//
// Parameters:
//   left:
//     The first object to compare.
//
//   right:
//     The second object to compare.
//
// Returns:
//     true if left is equal to right; otherwise, false.
public static bool operator ==( Type left, Type right );

Equals( Type o )

// Summary:
//     Determines if the underlying system type of the current System.Type is the
//     same as the underlying system type of the specified System.Type.
//
// Parameters:
//   o:
//     The System.Type whose underlying system type is to be compared with the underlying
//     system type of the current System.Type.
//
// Returns:
//     true if the underlying system type of o is the same as the underlying system
//     type of the current System.Type; otherwise, false.
public virtual bool Equals( Type o );

Question
Why would operator == be recommended over Equals( Type o ) when comparing Types?

I suggest that you read the excellent When is a Type not a Type? blog post by Brad Wilson. To summarize: a runtime type (represented by the internal type RuntimeType), managed by the CLR, is not always the same as a Type , which can be extended. Equals will check the underlying system type , whereas == will check the type itself.

A simple example:

Type type = new TypeDelegator(typeof(int));
Console.WriteLine(type.Equals(typeof(int))); // Prints True
Console.WriteLine(type == typeof(int));      // Prints False

原因很简单:在这种情况下,两者在功能上是等效的,而后者更具可读性。

From http://blogs.msdn.com/b/csharpfaq/archive/2004/03/29/when-should-i-use-and-when-should-i-use-equals.aspx

The Equals method is just a virtual one defined in System.Object, and overridden by whichever classes choose to do so. The == operator is an operator which can be overloaded by classes, but which usually has identity behaviour.

For reference types where == has not been overloaded, it compares whether two references refer to the same object - which is exactly what the implementation of Equals does in System.Object.

Value types do not provide an overload for == by default. However, most of the value types provided by the framework provide their own overload. The default implementation of Equals for a value type is provided by ValueType, and uses reflection to make the comparison, which makes it significantly slower than a type-specific implementation normally would be. This implementation also calls Equals on pairs of references within the two values being compared.

However, the main difference between the two types of comparison in normal use (where you're unlikely to be defining your own value types very often) is polymorphism. Operators are overloaded, not overridden, which means that unless the compiler knows to call the more specific version, it'll just call the identity version.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM