Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Abonnements

Que manque-t-il aux generics ?

Les generics (apparus avec la version 2.0 du framework .NET), c'est beau, c'est super, ça permet de factoriser le code, d'assurer une vérification plus stricte par le compilateur, de s'éviter des casts partout, etc. etc. Bref, que du bonheur  J

Oui mais…

Je trouve que les contraintes que l’on peut mettre sur les generics sont très limitées :

-       Forcer le type à être un type référence (where T : class)

-       Forcer le type à être un type valeur (where T : struct)

-       Forcer le type à être de type MyClass ou à en dériver (where T : MyClass)

-       Forcer le type à implémenter une interface (where T : MyInterface)

-       Forcer le type à dériver ou à implémenter un autre type (where T : K)

-       Forcer le type à être une classe et posséder une méthode public new sans paramètres (where T : new())

Personnellement, j’aurais aimé pouvoir lui préciser :

-       Lui préciser une signature de new (pas uniquement sans paramètre).

Ca éviterait de passer par le Activator.CreateInstance et permettrait de faire directement new T(…)

-       Forcer le type à être une interface

Pour utiliser typeof(BLLT).GetInterfaceMap(typeof(IT))

-       Forcer le type à ne pas être une classe abstraite

Dans le cas où le constructeur n’est pas public, la contrainte new ne marche pas (on peut d’ailleurs se demandait pourquoi dans le cas où la portée suffit). Avec Activator.CreateInstance, on a le droit d’instancier une classe même si son contructeur n’est pas public mais encore faut-il qu’elle ne soit pas abstraite.

-       Enfin et c’est un peu plus vicieux, j’aimerais pouvoir lui dire que mon type générique hérite d’une classe C OU a définit la conversion implicite entre lui-même et C.

Dans cette optique, il est regrettable de ne pas pouvoir définir de conversion implicite sur une interface.

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 :

Publié mercredi 5 décembre 2007 23:57 par Matthieu MEZIL

Classé sous : , ,

Commentaires

# re: Que manque-t-il aux generics ? @ jeudi 6 décembre 2007 11:33

Toujours sur les générics, le compilateur déduit quand il le peut le type.

Soit la méthode suivante :

public static void Test <T>(T toto)
{
}

Test<int>(1);

est équivalent à :

Test(1);

Cool Big Smile

Mais par contre, il ne sait pas le faire sur un new :

new KeyValuePair(1, 1);

ne compile pas. Il faudra écrire :

new KeyValuePair<int, int>(1, 1);

Ce qui est dommage car du coup, on ne peut pas créer de classe générique prenant un paramètre de type anonyme autrement que par reflection. Sad

Matthieu MEZIL

# re: Que manque-t-il aux generics ? @ jeudi 6 décembre 2007 14:09

"on ne peut pas créer de classe générique prenant un paramètre de type anonyme autrement que par reflection."

Si, c'est possible, puisque Select arrive a renvoyer une IEnumerable de type anonyme. Tu peux utiliser une méthode factory:

public static class MyFactory
{
  public static KeyValuePair<U, V> Create<U, V>(U u, V v)
  {
    return new KeyValuePair<U, V>(u, v);
  }
}

puis

var item = MyFactory.Create(new { Truc = "bonjour" }, 4);

RaptorXP

# re: Que manque-t-il aux generics ? @ jeudi 6 décembre 2007 14:39

"j’aimerais pouvoir lui dire que mon type générique hérite d’une classe C OU a définit la conversion implicite entre lui-même et C"

Certe on ne peut pas faire ca avec les contraintes, mais c'est facile à contourner:

- tu prends un Func

<T, C=""> dans ton constructeur, qui representera la conversion de ton type générique vers C

- tu passes ça au constructeur : x =&gt; x (qui sera interprété différement selon si T a une conversion implicite ou si T dérive de C)

- dans ta classe, tu convertis de cette façon :

T myVariable;

C myConvertedVariable = convert(myVariable);

où convert est le delegate passé au constructeur.

RaptorXP

# re: Que manque-t-il aux generics ? @ vendredi 7 décembre 2007 00:02

"Si, c'est possible, puisque Select arrive a renvoyer une IEnumerable de type anonyme. Tu peux utiliser une méthode factory"

- Je parlais de faire un new. Par une méthode bien sûr qu'on peut le faire.

""j’aimerais pouvoir lui dire que mon type générique hérite d’une classe C OU a définit la conversion implicite entre lui-même et C"

Certe on ne peut pas faire ca avec les contraintes, mais c'est facile à contourner :

tu prends un Func<T, C> dans ton constructeur, qui representera la conversion de ton type générique vers C"

- oui et non, il n'y a pas que que les classes qui peuvent être génériques, il y a aussi les méthodes et même si le fait de passer un delegué marche, c'est quand même un peu pénible.

Matthieu MEZIL

# re: Que manque-t-il aux generics ? @ vendredi 7 décembre 2007 02:05

Effectivement avec un new on ne peut pas, mais comme contournement, ca me parrait quand même beaucoup plus simple et plus efficace de passer par une méthode générique que d'utiliser la réfléxion.

RaptorXP

# re: Que manque-t-il aux generics ? @ vendredi 7 décembre 2007 09:31

Tu as entièrement raison mais c'est quand même vachement fun de faire :

var test = new { PropertyStr = "un", PropertyInt = 1 };
var list = Activator.CreateInstance(Type.GetType("System.Collections.Generic.List`1[" + test.GetType().ToString() + "]")) as IList;
list.Add(test);
list.Add(new { PropertyStr = "deux", PropertyInt = 2 });

Bon ok, c'est horrible Smile

Matthieu MEZIL

# re: Que manque-t-il aux generics ? @ vendredi 7 décembre 2007 15:09

tu aurais pu écrire :

...

Type listType = typeof(List&lt;&gt;).MakeGenericType(test.GetType());

var list = Activator.CreateInstance(listType) as IList;

...

pierrick

# re: Que manque-t-il aux generics ? @ lundi 10 décembre 2007 12:01

pierrick : cool, je connaissais pas.

Matthieu MEZIL

# re: Que manque-t-il aux generics ? @ mercredi 26 décembre 2007 22:56

Matthieu, faut que tu révises les webcasts "C# 2.0, un an après". :)

Mitsu

# re: Que manque-t-il aux generics ? @ samedi 29 décembre 2007 13:50

Aie, un webcast de Mitsu que je ne connais pas par coeur, ma réputation au sein du MFC va en prendre un coup lol

Matthieu MEZIL

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01