2009-03-07 9 views
11

Was bedeutet where T : somevalue? Ich habe gerade einen Code gesehen, der where T : Attribute sagte. Ich denke, das hat etwas mit Generika zu tun, aber ich bin mir nicht sicher, was das bedeutet oder was es tut.Was bedeutet "where T: somevalue"?

Weiß jemand?

Antwort

28

Es ist ein constraint on a type parameter, was bedeutet, dass der Typ T auf eine generische Klasse gegeben oder eine Methode aus der Klasse Attribute

Zum Beispiel erben müssen:

public class Foo<T> : 
    where T : Attribute 
{ 
    public string GetTypeId(T attr) { return attr.TypeId.ToString(); } 
// .. 
} 

Foo<DescriptionAttribute> bar; // OK, DescriptionAttribute inherits Attribute 
Foo<int> baz; // Compiler error, int does not inherit Attribute 

Dies ist nützlich, weil es die allgemeine erlaubt Klasse Dinge mit Objekten des Typs T mit dem Wissen zu tun, dass alles, was ein T ist, auch ein Attribute sein muss.

Im Beispiel oben, es ist in Ordnung für GetTypeId die TypeId von attr abzufragen, weil TypeId eine Eigenschaft eines Attribute ist, und weil attr ein T ist, muss es sich um eine Art sein, die von Attribute erbt.

Constraints können auch auf generische Methoden verwendet werden, mit der gleichen Wirkung:

public static void GetTypeId<T>(T attr) where T : Attribute 
{ 
    return attr.TypeId.ToString(); 
} 

Es gibt andere Einschränkungen, die Sie auf einer Art platzieren können; von MSDN:

where T: struct

Das Argument Typ muss ein Wert Typ sein. Jeder Werttyp außer Nullable kann angegeben werden.

where T : class

Das Argument Typ muss eine Referenz Typ sein; Dies gilt auch für jede Klasse, Schnittstelle, Delegat oder Array-Typ.

where T : new()

Das Argument Typ muss einen öffentlichen parameterlosen Konstruktor hat. Wenn zusammen mit anderen Einschränkungen verwendet wird, muss die new() - Einschränkung zuletzt angegeben werden.

where T : <base class name>

Das Argument Typ muss aus der angegebenen Basisklasse sein oder abzuleiten.

where T : <interface name>

Das Argument Typ muss die angegebene Schnittstelle oder implementieren. Mehrere Schnittstellenbeschränkungen können angegeben werden. Die einschränkende Schnittstelle kann auch generisch sein.Dies wird als ein nackter Typ constraint

where T : U

Der Typargument für T geliefert werden, müssen aus dem Argument oder für U. geliefert abzuleiten.

+0

+1 Dies ist ziemlich umfangreich. Ich wünschte, ich könnte eine Antwort favorisieren. – Sung

1

Die Klausel where wird verwendet, um die Argumente zu begrenzen, die bei der Verwendung von Generika übergeben werden können. Wenn Sie eine generische Klasse erstellen, ist es möglicherweise von Interesse, einen Argumenttyp anzugeben, je nachdem, wie Sie T in Ihrer Klasse verwenden möchten. Wenn es etwas anderes außer was System.Object tun kann, dann ist es wahrscheinlich am besten, eine constraint zu verwenden, da Sie einen Fehler bei der Kompilierung gegen eine Laufzeit erhalten.

Beispiel

Wenn Sie eine Klasse

class Person<T> where T : System.IComparable<T> 
{ 
    //can now use CompareTo 
} 

Sie können bei dieser Klasse nichts nicht passieren, die nicht IComparable nicht implementiert. So ist es jetzt sicher, CompareTo für alles zu verwenden, was in die Person-Klasse übergeben wird.

1

Es ist eine Möglichkeit, den als generische Argumente verwendeten Typ einzuschränken. Also:

where T : SomeType 

Mittel, die T entweder von Sometype ableiten muss oder die Schnittstelle Sometype

5

Zusätzlich zu implementieren, was die anderen sagten, Sie haben die folgende zu:

  • neu () - T muss einen Standardkonstruktor haben
  • Klasse - T muss ein Referenztyp sein
  • struct - T muss ein Wert sein