La réification signifie en général (en dehors de l'informatique) "de faire quelque chose de réel".
Dans la programmation, quelque chose est réifiée , si nous sommes capables d'accéder à des informations à ce sujet dans le langage lui-même.
Pour les deux entièrement non-génériques des exemples liés de quelque chose de C# et n'a pas réifiée, nous allons prendre les méthodes et les accès à la mémoire.
OO langues ont généralement des méthodes, (et beaucoup de ceux qui n'ont pas de fonctions qui sont semblables, mais n'est pas lié à une classe). En tant que tel, vous pouvez définir une méthode dans une telle langue, l'appeler, peut-être le remplacer, et ainsi de suite. Pas toutes ces langues vous permettent de réellement traiter avec la méthode elle-même en tant que données d'un programme. C# (et vraiment, .NET plutôt que C#) ne vous permettent de faire usage de l' MethodInfo
des objets représentant les méthodes, donc en C# méthodes sont réifiée. Méthodes en C# sont "des objets de première classe".
Toutes les langues ont quelques moyens pour accéder à la mémoire d'un ordinateur. Dans un langage de bas niveau comme le C, nous pouvons traiter directement avec la correspondance entre les adresses numériques utilisés par l'ordinateur, de sorte que les goûts de int* ptr = (int*) 0xA000000; *ptr = 42;
est raisonnable (tant que nous avons une bonne raison de soupçonner que l'accès à la mémoire de l'adresse 0xA000000
dans cette façon de ne pas faire sauter quelque chose). En C#, cela n'est pas raisonnable (nous pouvons juste au sujet de la force .NET, mais avec le .NET gestion de la mémoire bouger les choses autour d'elle n'est pas très susceptibles d'être utiles). C# n'est pas réifiée des adresses de mémoire.
Donc, comme refied signifie "fait de réels" un "réifiée de type" est un type qu'on peut "parler" dans la langue en question.
Dans les génériques, cela signifie deux choses.
L'une est qu' List<string>
est un type comme string
ou int
. On peut comparer ce type, son nom, et en savoir davantage à ce sujet:
Console.WriteLine(typeof(List<string>).FullName); // System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Console.WriteLine(typeof(List<string>) == (42).GetType()); // False
Console.WriteLine(typeof(List<string>) == Enumerable.Range(0, 1).Select(i => i.ToString()).ToList().GetType()); // True
Console.WriteLine(typeof(List<string>).GenericTypeArguments[0] == typeof(string)); // True
Une conséquence de cela est que l'on peut "parler" d'une méthode générique (ou une méthode d'une classe générique) types des paramètres dans la méthode elle-même:
public static void DescribeType<T>(T element)
{
Console.WriteLine(typeof(T).FullName);
}
public static void Main()
{
DescribeType(42); // System.Int32
DescribeType(42L); // System.Int64
DescribeType(DateTime.UtcNow); // System.DateTime
}
En règle générale, faire ce trop est "puant", mais il a beaucoup de cas utiles. Par exemple, regardez:
public static TSource Min<TSource>(this IEnumerable<TSource> source)
{
if (source == null) throw Error.ArgumentNull("source");
Comparer<TSource> comparer = Comparer<TSource>.Default;
TSource value = default(TSource);
if (value == null)
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
do
{
if (!e.MoveNext()) return value;
value = e.Current;
} while (value == null);
while (e.MoveNext())
{
TSource x = e.Current;
if (x != null && comparer.Compare(x, value) < 0) value = x;
}
}
}
else
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
if (!e.MoveNext()) throw Error.NoElements();
value = e.Current;
while (e.MoveNext())
{
TSource x = e.Current;
if (comparer.Compare(x, value) < 0) value = x;
}
}
}
return value;
}
Ce n'est pas faire beaucoup de comparaisons entre le type d' TSource
et les divers types de comportements différents (généralement un signe que vous ne devriez pas avoir utilisé des médicaments génériques à tous) mais il n'est partagé entre un chemin de code pour les types qui peuvent être null
(doit renvoyer null
si aucun élément trouvé, et ne doit pas faire des comparaisons pour trouver le minimum si l'un des éléments de comparaison est null
) et le chemin de code pour les types qui ne peuvent pas être null
(à lancer si aucun élément trouvé, et ne pas avoir à vous soucier de la possibilité de null
des éléments).
Parce qu' TSource
"le réel" dans la méthode, cette comparaison peut être faite soit au moment de l'exécution ou de jitting temps (généralement jitting temps, certainement le cas ci-dessus au jitting temps et de ne pas produire du code machine pour le chemin d'accès pas pris) et nous avoir une "vraie" version de la méthode pour chaque cas. (Même si, comme l'optimisation, le code de l'ordinateur est partagé par différentes méthodes pour les différentes de référence de type de type de paramètres, car il peut être, sans affecter le présent, et par conséquent, nous pouvons réduire la quantité de code machine jitted).
(Il n'est pas commun pour parler de la réification de types génériques en C#, sauf si vous traitent également de Java, car en C#, nous venons de prendre cette réification de tous les types sont réifiée. En Java, les non-types génériques sont appelés réifiée parce que c'est une distinction entre eux et les types génériques).