Generische Einschränkungen für die Funktion

8

Ich möchte eine generische Funktion schreiben, die eine Einschränkung für den Typ hat. Speziell möchte ich so etwas:

%Vor%

Der Punkt ist, dass Sie überprüfen können, ob sich ein Element in einer Parameterliste befindet:

%Vor%

Der Compiler krächzt jedoch auf der Gleichheitslinie. Daher möchte ich eine Einschränkung für den Typ festlegen, in dem IEquatable implementiert wird. Einschränkungen scheinen jedoch nur auf Klassenebene zu funktionieren. Ist das korrekt oder gibt es eine Möglichkeit, dies generisch zu spezifizieren?

    
JessicaB 25.09.2010, 17:00
quelle

4 Antworten

7

Generische Constraints funktionieren auch mit generischen Methoden:

%Vor%

ABER, IEquatable<T> definiert nicht operator == , nur Equals(T) .

Also sollten Sie Equals() verwenden und Sie brauchen nicht einmal die Einschränkung dafür: Equals(object) ist Mitglied von object .

Vergessen Sie auch nicht, dass Equals nicht funktioniert, wenn das Objekt null ist.

    
svick 25.09.2010, 17:12
quelle
11

Andere haben IEquatable<T> erwähnt, was sicherlich eine gute potentielle Einschränkung darstellt.

Eine weitere denkbare Option ist EqualityComparer<T>.Default , die IEquatable<T> verwendet, falls verfügbar, aber sonst auf object.Equals(object) zurückfällt. Dies bedeutet, dass Sie sie mit Typen verwenden können, die Generika vorgeben, aber Equals überschreiben, zum Beispiel:

%Vor%

Beachten Sie, dass der standardmäßige Gleichheitsvergleich auch Nullreferenzen berücksichtigt, so dass Sie sich keine Gedanken über diese selbst machen müssen. Wenn der Typ T object.Equals(object) oder IEquatable<T> nicht überschrieben hat, erhalten Sie Semantik der Referenzgleichheit (d. H. Es wird nur true zurückgegeben, wenn sich die genaue Referenz im Array befindet).

Ein paar andere Punkte:

  • Ihr Wunsch, sich an einen einzigen Ausgangspunkt zu halten, macht den Code weniger lesbar, IMO. Hier ist keine zusätzliche Variable erforderlich:

    %Vor%
  • LINQ enthält bereits eine Methode hierfür, Contains , damit Sie den Code vereinfachen können:

    %Vor%
  • Array enthält diese Funktionalität auch effektiv mit IndexOf :

    %Vor%
  • Ihre Methode ist vielleicht ein wenig irreführend benannt, da args ein Array ist, nicht ein List<T> .

Jon Skeet 25.09.2010 17:20
quelle
1

Der Operator '==' wird im Allgemeinen nur für unveränderliche Typen verwendet - (eingebaute Werttypen oder benutzerdefinierte unveränderliche Typen, die den Operator == überladen haben. Wenn Sie ihn nicht überladen, wenn Sie ihn für Referenztypen verwenden (außer strings) es gibt nur true zurück, wenn beide Variablen auf die gleiche Instanz des Typs verweisen (gleiches Objekt). Es würde false zurückgeben, wenn die beiden Veriables auf verschiedene Instanzen des Typs verweisen, auch wenn beide die gleichen internen Datenwerte haben / p>

Also müssen Sie den Typ T auf die Typen beschränken, die die Equals() -Funktion implementieren, die bestimmen soll, ob zwei Instanzen eines beliebigen Typs "gleich" sind und nicht nur, dass sie auf dieselbe Instanz verweisen. und benutze das stattdessen. Die eingebaute Schnittstelle IEquatable<T> drückt dies für Sie aus. (ein bisschen wie IComparable<T> erfordert, dass ein Typ eine CompareTo() Funktion hat)
Außerdem können Sie Ihre Funktion viel übersichtlicher und klarer gestalten ...

versuche das:

%Vor%

Sie sollten auch den Unterschied zwischen Equals () und == verstehen und entscheiden, was für Ihre Absicht besser geeignet ist ... Auschecken diese Referenz für weitere Informationen.

    
Charles Bretana 25.09.2010 17:03
quelle
0

Ersetzen Sie einfach

%Vor%

mit

%Vor%     
Matthew Manela 25.09.2010 17:04
quelle

Tags und Links