Quels sont quelques exemples d'utilisation de génériques dans C #/VB.NET et pourquoi voudriez-vous utiliser des génériques?
Vous déclarez simplement un type ou une méthode avec des balises supplémentaires pour indiquer les bits génériques:
class Foo<T> {
public Foo(T value) {
Value = value;
}
public T Value {get;private set;}
}
Ce qui précède définit un type générique Foo
"of T
", où T
est fourni par l'appelant. Par convention, les arguments de type générique commencent par T. S'il n'y en a qu'un, T
va bien - sinon, appelez-les tous utilement: TSource
, TValue
, TListType
etc.
Contrairement aux modèles C++, les génériques .NET sont fournis par le runtime (et non par les astuces du compilateur). Par exemple:
Foo<int> foo = new Foo<int>(27);
Toutes les T
s ont été remplacées par int
dans ce qui précède. Si nécessaire, vous pouvez restreindre les arguments génériques avec des contraintes:
class Foo<T> where T : struct {}
Maintenant, Foo<string>
refusera de compiler - car string
n'est pas une structure (valeur-type). Les contraintes valides sont:
T : class // reference-type (class/interface/delegate)
T : struct // value-type except Nullable<T>
T : new() // has a public parameterless constructor
T : SomeClass // is SomeClass or inherited from SomeClass
T : ISomeInterface // implements ISomeInterface
Les contraintes peuvent également impliquer d'autres arguments de type génériques, par exemple:
T : IComparable<T> // or another type argument
Vous pouvez avoir autant d'arguments génériques que vous avez besoin:
public struct KeyValuePair<TKey,TValue> {...}
Autres choses à noter:
Foo<int>
est distinct de celui sur Foo<float>
.par exemple:
class Foo<T> {
class Bar<TInner> {} // is effectively Bar<T,TInner>, for the outer T
}
Exemple 1: vous voulez créer une triple classe
Class Triple<T1, T2, T3>
{
T1 _first;
T2 _second;
T3 _Third;
}
Exemple 2: Une classe d'assistance qui analysera toute valeur enum pour un type de données donné
static public class EnumHelper<T>
{
static public T Parse(string value)
{
return (T)Enum.Parse(typeof(T), value);
}
}
Une utilisation courante et extrêmement utile des génériques est celle des classes de collection fortement typées. Traditionnellement, toutes les classes de collection devaient être des objets transmis et renvoyer des objets lorsqu'elles étaient interrogées. Vous deviez gérer vous-même toutes les conversions de types. Avec les génériques, vous n’avez pas à le faire. Vous pouvez avoir List (Of Inger), et quand vous lui demandez des valeurs, vous obtenez des entiers. Vous n'obtiendrez pas d'objets que vous devrez ensuite convertir en nombres entiers.
private void button1_Click_1(object sender, RoutedEventArgs e)
{
TextValue<string, int> foo = new TextValue<string, int>("",0);
foo.Text = "Hi there";
foo.Value = 3995;
MessageBox.Show(foo.Text);
}
class TextValue<TText, TValue>
{
public TextValue(TText text, TValue value)
{
Text = text;
Value = value;
}
public TText Text { get; set; }
public TValue Value { get; set; }
}
Les raisons les plus courantes et les cas d'utilisation des génériques sont décrits dans la documentation MSDN mentionnée précédemment. Un avantage des génériques que je voudrais ajouter est qu'ils peuvent améliorer le support des outils dans le processus de développement. Les outils de refactoring tels que ceux intégrés à Visual Studio ou ReSharper s'appuient sur une analyse de type statique pour fournir une assistance lors du codage. Comme les génériques ajoutent généralement plus d’informations sur le type à votre modèle d’objet, il existe plus d’informations sur ces outils pour l’analyse et l’aide à la codification.
Sur le plan conceptuel, les génériques vous aident à résoudre des problèmes "transversaux" indépendamment de votre domaine d'application. Que vous développiez une application financière ou une librairie, vous devrez tôt ou tard conserver des collections d'objets, qu'il s'agisse de comptes, de livres ou autre. La mise en place de telles collections nécessite généralement peu de connaissances en la matière. Par conséquent, les collections génériques fournies avec le .NET Framework sont un exemple principal pour un cas d'utilisation de générique.
Un exemple de base serait:
class Other{
class Generic<T>
{
void met1(T x);
}
static void Main()
{
Generic<int> g = new Generic<int>();
Generic<string> s = new Generic<string>();
}
}
private void button1_Click_1(object sender, RoutedEventArgs e)
{
TextValue<string, int> foo;
List<TextValue<string, int>> listTextValue = new List<TextValue<string, int>>();
for (int k = 0; k < 5; ++k)
{
foo = new TextValue<string, int>("",0);
foo.Text = k.ToString();
foo.Value = k;
listTextValue.Add(foo);
otherList.
MessageBox.Show(foo.Text);
}
}
class TextValue<TText, TValue>
{
public TextValue(TText text, TValue value){Text = text; Value = value;}
public TText Text { get; set; }
public TValue Value { get; set; }
}