115 votes

« Un type générique ouvert » dans .NET, c’est quoi exactement ?

J'ai été en passant par Asp.Net MVC leçon et a appris que, pour une méthode pour être considérée comme une action d'un contrôleur,

  • Il ne doit pas avoir un "open type générique"

Je comprends génériques un peu et de les utiliser dans une certaine mesure, mais:

  • Ce qui est un ouvert de type générique .Net.
  • Est-il une telle chose comme un fermé de type générique?
  • Ouvert de type générique est un terme qui n'est pas utilisé très souvent. Ce qui est utilisé / confondre avec elle ?

190voto

Mehrdad Afshari Points 204872

Le langage C# définit un type ouvert à un type qui est soit un argument de type ou d'un type générique défini avec des inconnus arguments de type:

Tous les types peuvent être classés comme de type ouvert ou fermé types. Un type est un type qui implique des paramètres de type. Plus précisément:

  • Un paramètre de type définit un type ouvert.
  • Un type tableau est un type ouvert si et seulement si son type d'élément est un type ouvert.
  • Un type construit est un type ouvert si et seulement si l'un ou plusieurs de ses arguments de type est un type ouvert. Un construit imbriquée type est un type ouvert si et seulement si l'un ou plusieurs de ses arguments de type ou le type des arguments de son contenant type(s) est un type ouvert.

Un type fermé est un type qui n'est pas un type ouvert.

Par conséquent, T, List<T>, et Dictionary<string,T>, et Dictionary<T,U> sont tous de type ouvert (T et U sont des arguments de type) alors qu' List<int> et Dictionary<string,int> sont fermés types.

Il y a un concept connexe: Un indépendant de type générique est un type générique avec non spécifié type d'arguments. Un indépendant type ne peuvent pas être utilisées dans les expressions autres que typeof() et vous ne pouvez pas l'instancier ou appeler ses méthodes. Par exemple, List<> et Dictionary<,> sont indépendant des types.

Afin de clarifier la distinction subtile entre un type ouvert et indépendant de type:

class Program {
   static void Main() { Test<int>(); }
   static void Test<T>() {
      Console.WriteLine(typeof(List<T>)); // Print out the type name
   }
}

Si vous exécutez cet extrait de code, il va imprimer

System.Collections.Generic.List`1[System.Int32]

qui est le CLR nom List<int>. Il est clair au moment de l'exécution que l'argument type est - System.Int32. Cela rend List<T> un lié de type ouvert.

Au moment de l'exécution, vous pouvez utiliser la réflexion pour lier les arguments de type de type non spécifié les paramètres de unbound types génériques avec l' Type.MakeGenericType méthode:

Type unboundGenericList = typeof(List<>);
Type listOfInt = unboundGenericList.MakeGenericType(typeof(int));
if (listOfInt == typeof(List<int>))
     Console.WriteLine("Constructed a List<int> type.");

Vous pouvez vérifier si un type est un indépendant de type générique (générique de la définition de type) à partir de laquelle vous pouvez construire des types liés à l' Type.IsGenericTypeDefinition de la propriété:

Console.WriteLine(typeof(Dictionary<,>).IsGenericTypeDefinition); // True
Console.WriteLine(typeof(Dictionary<int,int>).IsGenericTypeDefinition); // False

Pour obtenir le unbound type à partir d'un type construit au moment de l'exécution, vous pouvez utiliser l' Type.GetGenericTypeDefinition méthode.

Type listOfInt = typeof(List<int>);
Type list = listOfInt.GetGenericTypeDefinition(); // == typeof(List<>)

Notez que pour un type générique, vous pouvez avoir un complètement indépendant de la définition de type, ou complètement lié définition. Vous ne pouvez pas lier certains paramètres de type et de laisser les autres unbound. Par exemple, vous ne pouvez pas avoir d' Dictionary<int,> ou Dictionary<,string>.

10voto

leppie Points 67289

Juste pour ajouter :

(ou plus précisément ) est toujours un type ouvert.

Exemple :

7voto

John Feminella Points 116878

Un type générique" est juste un type générique qui n'a pas encore son type spécifié (par exemple, CargoCrate<T>). Il est "fermé" une fois qu'un type de béton a été attribué (par exemple, CargoCrate<Widget>).

Par exemple, disons que vous avez quelque chose comme ceci:

public class Basket<T> {
  T[] basketItems;
}

public class PicnicBlanket<T> {
  Basket<T> picnicBasket;   // Open type here. We don't know what T is.
}

                                 // Closed type here: T is Food.
public class ParkPicnicBlanket : PicnicBlanket<Food> {
}

Ici, picnicBasket'de type s est ouvert: rien n'a encore été attribué à l' T. Lorsque vous effectuez un béton PicnicBlanket avec un type spécifique-par exemple, en écrivant PicnicBlanket<Food> p = new PicnicBlanket<Food>() -- nous l'appelons maintenant fermé.

6voto

Gorpik Points 7276

Il y a trois sortes de types génériques. Pour faire court, dans ce (simplifié) de la déclaration:

public class Dictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
  • Dictionary<TKey, TValue> est une surabondance de type générique.

  • KeyValuePair<TKey, TValue> est, dans ce cas, une construction ouverte de type générique. Il dispose d'un certain type de paramètres, mais ils sont déjà définies ailleurs (dans le Dictionnaire, dans ce cas).

  • Dictionary<string, int> serait un construit fermé de type générique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X