C# 3.0 : Les types anonymes en détail
Les types anonymes sont ma nouveauté préférée de C# 3.0. Ils sont très intuitifs à utiliser, mais tout le monde ne connait pas leurs caractéristiques exactes. Je me charge donc de les rappeler.
- Vous pouvez déclarer une variable locale de type anonyme de la façon suivante :
var variableTypeAnonyme = new { FirstName = "Flavien", Age = 23, DateOfBirth = new DateTime(1984, 11, 15) };
Le compilateur va donc créer une classe générique qui aura les propriétés correspondantes, et dont les types sont inférés grâce à l'expression d'initialisation (ici, FirstName de type string, Age de type int et DateOfBirth de type DateTime).
Etant donné que le type n'a pas de nom, l'utilisation du mot-clé var est obligatoire. Il est également obligatoire pour les types génériques dont un des types paramètres est un type anonmyme (par exemple IEnumerable<T> lorsque T est un type anonyme).
- Pour que deux variables de types anonymes soient de même type, il faut que ces deux variables aient été déclarées avec les mêmes propriétés, mêmes types pour chacune des propriétés et que les propriétés soient déclarées dans le même ordre. Par exemple, ces deux variables ne sont pas de même type (les propriétés sont inversées) :
var variableTypeAnonyme = new { FirstName = "Flavien", Age = 23, DateOfBirth = new DateTime(1984, 11, 15) };
var variableTypeAnonyme = new { FirstName = "Britney", DateOfBirth = new DateTime(1981, 12, 2), Age = 26 };
- Les variables de type anonyme sont immutables, c'est à dire que les propriétés n'ont pas de set. Il n'est plus possible de les modifier après l'initialisation.
- Les variables de type anonyme sont confinées dans la méthode dans laquelle elles sont définies, puisqu'on ne peut pas retourner ou passer en argument une variable de type "var". Le seul moyen de retourner une variable de type anonyme est de la convertir en object, et il sera par la suite impossible de reconvertir la variable dans son type d'origine puisque il est interdit de convertir vers un type anonyme. Retourner une variable de type anonyme est donc inutile à moins d'utiliser la réflexion. Cela évite la propagation incontrôlée des types anonymes.
- Il n'est pas possible d'ajouter de méthode aux types anonymes, ceux-ci sont juste des containeurs de données.
- La méthode ToString est surchargée et utilise la méthode ToString de chacun des attributs. Le format est le suivant :
{ FirstName = Flavien, Age = 23, DateOfBirth = 11/15/1984 12:00:00 AM }
- Egalité : La méthode Equals est surchargée de telle façon que deux instances du même type anonyme sont égales si toutes leurs propriétés sont égales, au sens de la comparaison par défaut des types des propriétés. Donc les deux instances suivantes seront considérées comme égales :
var variableTypeAnonyme = new { FirstName = "Flavien", Age = 23, DateOfBirth = new DateTime(1984, 11, 15) };
var variableTypeAnonyme2 = new { FirstName = "Flavien", Age = 23, DateOfBirth = new DateTime(1984, 11, 15) };
La méthode GetHashCode est également surchargée pour refléter cette égalité. Le code de hashage est par ailleurs construit de façon intelligente pour tenir compte de tous les membres. Donc les types anonymes peuvent être utilisés efficacement comme clés dans un Dictionary par exemple.
Le compareur par défaut (Comparer<T>.Default) d'un type anonyme est donc tout à fait utilisable pour effectuer une comparaison profonde (les membres sont comparés deux à deux) de deux instances du même type anonyme.
La conséquence de ceci est qu'il est possible d'utiliser un type anonyme comme clé dans une clause join ou group dans une expression LINQ. Cela peut être utile si vous souhaitez par exemple grouper les résultats d'une requête en utilisant deux critères à la fois :
var result = from person in list
group person by new { LastName = person.LastName, YearOfBirth = person.DateOfBirth.Year };
Les types anonymes n'implémentent aucune méthode de comparaison (IComparer) de supériorité ou infériorité, il est donc impossible de les utiliser dans une clause orderby.
Pour plus d'infos sur les types anonymes : http://msdn2.microsoft.com/en-us/library/bb397696(VS.90).aspx.
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :