2012-02-10 12 views
33

Resharper sugeruje, że dodaje się zmieniło od:C# Typ Porównanie: Type.Equals vs == operatora

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

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

Do:

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

operatora ==

// 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); 

Równe (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); 

Pytanie
Dlaczego operator == być zalecana przez Equals(Type o) przy porównywaniu typy?

Odpowiedz

32

Proponuję przeczytać znakomity blog blogu when is a type not a type? autorstwa Brada Wilsona. Podsumowując: typ środowiska wykonawczego (reprezentowany przez typ wewnętrzny RuntimeType), zarządzany przez CLR, nie zawsze jest taki sam jak typ Type, który można rozszerzyć. Equals sprawdzi underlying system type, natomiast == sprawdzi sam typ.

Prosty przykład:

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

Powód jest prosty: dwa są funkcjonalnie równoważne w tym przypadku, a drugi jest bardziej czytelny.

+0

R # zazwyczaj sugerują coś i dostarczyć ważny powód; w tym przypadku, jeśli są funkcjonalnie równoważne, mam wątpliwości, czy sugestia dotyczy czytelności, która jest subiektywna. Zastanawiam się, czy jest inny powód, dla którego jest to sugerowane? –

+0

@MetroSmurf - R # często sugeruje rzeczy ze względu na czytelność (na przykład zmniejszanie zagnieżdżania w instrukcjach if). –

+5

To jest prawdopodobnie zamierzony powód, ale ponieważ nie są one funkcjonalnie równoważne w tym przypadku, to z pewnością jest to błąd w Resharperze? –

1

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

równości metoda jest tylko jeden wirtualny zdefiniowane w System.Object, a przesłonięte przez którykolwiek zajęcia wybrać, aby to zrobić. Operator == jest operatorem , który może być przeciążony przez klasy, ale który zwykle ma zachowanie tożsamościowe .

Dla typów odniesienia, w których == nie zostało przeciążone, porównuje się , czy dwa odniesienia odnoszą się do tego samego obiektu - co jest dokładnie takie, jak implementacja równań w System.Object.

Typy wartości nie zapewniają przeciążenia domyślnie ==. Jednak większość typów wartości zapewnianych przez framework zapewnia ich własne przeciążenie . Domyślna implementacja równań dla typu wartości to dostarczona przez ValueType i wykorzystuje odbicie, aby dokonać porównania, , co czyni go znacznie wolniejszym niż typowa implementacja typu . Ta implementacja również wywołuje Równa się parom odniesień w obrębie porównywanych wartości.

Jednak główna różnica między dwoma typami porównań w normalnym użytkowaniu (gdzie bardzo rzadko definiuje się własne typy wartości ) to polimorfizm. Operatory są przeciążane, a nie zastępowane, co oznacza, że ​​jeśli kompilator nie zadzwoni na bardziej szczegółową wersję , po prostu wywoła wersję tożsamości.