2009-03-07 18 views
11

Che cosa significa "where T : somevalue"? Ho appena visto un codice che diceva where T : Attribute. Penso che questo abbia qualcosa a che fare con i generici, ma non sono sicuro di cosa significhi o cosa stia facendo.Che cosa significa "dove T: somevalue" significa?

Qualcuno sa?

risposta

28

È un constraint on a type parameter, il che significa che il tipo T dato a una classe generica o metodo deve ereditare dalla classe Attribute

Ad esempio:

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 

Ciò è utile, perché permette al generico classe di fare cose con oggetti di tipo T con la consapevolezza che tutto ciò che è un T deve essere anche un Attribute.

Nell'esempio sopra, va bene per GetTypeId per interrogare il TypeId di attr perché TypeId è una proprietà di un Attribute, e perché è un attrT deve essere un tipo che eredita dalla Attribute.

I vincoli possono essere utilizzati anche su metodi generici, con lo stesso effetto:

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

Ci sono altri vincoli è possibile inserire su un tipo; da MSDN:

where T: struct

L'argomento tipo deve essere un valore tipo. È possibile specificare qualsiasi tipo di valore tranne Nullable .

where T : class

L'argomento tipo deve essere un riferimento tipo; questo vale anche per qualsiasi classe, interfaccia , delegato o tipo di matrice.

where T : new()

L'argomento di tipo deve avere un costruttore senza parametri pubblico. Quando viene utilizzato insieme ad altri vincoli, è necessario specificare il limite new() per ultimo.

where T : <base class name>

L'argomento tipo deve essere o derivare dalla classe base specificata.

where T : <interface name>

L'argomento tipo deve essere o implementare l'interfaccia specificata. I vincoli di interfaccia multipli possono essere specificati . L'interfaccia vincolante può anche essere generica.

where T : U

Il tipo di argomento fornito per T deve essere o derivare dalla tesi dotazione per U. Questo è chiamato un nudo tipo di vincolo.

+0

+1 Questo è piuttosto completo. Vorrei poterti dare una risposta preferita. – Sung

1

La clausola where viene utilizzata per limitare gli argomenti che possono essere inoltrati quando si utilizzano i generici. Quando crei una classe generica, potrebbe essere nel tuo interesse specificare un tipo di argomento a seconda di come pensi di usare T nella tua classe. Se qualcosa oltre a ciò che System.Object può fare, probabilmente è meglio usare uno constraint poiché si otterrà un errore di compilazione rispetto a un runtime.

esempio

Se si crea una classe

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

Non si può non passare questo nulla di classe che non implementa IComparable. Quindi è ora sicuro utilizzare CompareTo su tutto ciò che viene passato nella classe Person.

1

È un modo per limitare il tipo utilizzato come argomenti generici. Quindi:

where T : SomeType 

Mezzi che T deve o derivare da SomeType o implementare l'interfaccia SomeType

5

Inoltre quello che gli altri hanno detto, si ha la seguente troppo:

  • nuovo (- T deve avere il costruttore predefinito
  • classe - T deve essere un tipo di riferimento
  • struct - T deve essere un tipo di valore