2009-12-13 14 views
34

folgendem Grund nicht nicht kompiliert:-Test für die Gleichstellung auf den Standardwert

public void MyMethod<T>(T value) 
{ 
    if (value == default(T)) 
    { 
     // do stuff 
    } 
} 

Fehler: Operator '==' cannot be applied to operands of type 'T' and 'T'

ich kann nicht value == null weil T kann eine Struktur sein.
Ich kann value.Equals(default(T)) nicht verwenden, weil valuenull sein kann.
Was ist der richtige Weg, um den Standardwert auf Gleichheit zu testen?

+2

antwortete auf Kommentar; und für Informationen ist 'EqualityComparer ' die Standardimplementierung, die von der BCL verwendet wird, zum Beispiel in 'Dictionary <,>'. –

+2

möglich duplicate von http://stackoverflow.com/questions/65351/null-or-default-comparsion-of-generic-argument-in-c-sharp – nawfal

Antwort

53

Boxen Um zu vermeiden, für struct/Nullable<T>, würde ich verwenden:

if (EqualityComparer<T>.Default.Equals(value,default(T))) 
{ 
    // do stuff 
} 

Dieser jede T unterstützt, die IEquatable<T> implementieren, object.Equals als Backup verwenden und Griffe null usw. (und hob Betreiber für Nullable<T>) automatisch.

Es gibt auch Comparer<T>.Default, die Vergleichstests behandelt. Dies behandelt T, die implementieren IComparable<T>, zurückfallen auf IComparable - wieder Handhabung null und hob Betreiber.

+0

Sie sagen, dass "EqualityComparer .Default.Equals" eine bessere Leistung als "Object.Equals" hat, oder dass es in einigen Fällen einen korrekten Wert geben würde, den "Object.Equals" nicht hätte? – Greg

+9

Bessere Leistung (weniger Boxen); betrachte 'T = int'; Um 'object.Equals' zu nennen, muss man' value' und 'default (T)' angeben - das sind zwei zusätzliche Heap-Zuweisungen + GC. Mit 'EqualityComparer 'hat es 3 verschiedene zugrunde liegende Implementierungen -' class', 'Nullable ' und 'struct' - es kann dann alles (einschließlich' null' Tests) ohne ** irgendwelche ** boxen. Die Arbeit, herauszufinden, welche Implementierung zu verwenden ist, wird nur einmal pro Typ durchgeführt und zwischengespeichert, also immer noch sehr schnell. –

+0

Danke, Marc! Ihre Erklärung ist wunderbar – Greg

21

Was

object.Equals(value, default(T)) 
+0

Ich wusste, dass es einfach sein sollte. Vielen Dank. – Greg

+1

+1. Geprüft. Funktioniert korrekt mit verschiedenen Typen: 'MyMethod (0); MyMethod (null); MyMethod (null); '- gibt in jedem Fall wahr zurück. –

Verwandte Themen