Comment restreindre T aux types de valeur en utilisant une contrainte?

Je veux limiter les types possibles que N peut accepter en utilisant une contrainte. Je souhaite limiter N à être un int ou un nombre décimal.

public static Chart PopulateInto(List yAxis, List xAxis) where N : int, decimal { // Do stuff here } 

Toute aide appréciée …

Malheureusement, il n’est pas possible de spécifier des contraintes de type génériques n’autorisant que des types de valeur spécifiques. Plus précisément, cela n’aurait pas beaucoup de sens même si cela était autorisé.

Vous êtes autorisé à spécifier une classe en tant que contrainte générique, mais comme vous pouvez hériter de classes, la contrainte définit ainsi le seuil minimal des types que vous êtes autorisé à utiliser.

Si cela était autorisé pour les types de valeur, où vous ne pouvez pas hériter de ces types, vous vous limiteriez à ce type.

Ainsi, vous ne pouvez pas faire cela, mais vous avez quelques alternatives:

  • Vous pouvez le déclarer sans contrainte et gérer le problème au moment de l’exécution. Je ne recommanderais pas cette façon
  • Vous pouvez déclarer des surcharges prenant les types spécifiques qui vous intéressent.

    Comme vous n’avez que deux types de ce type, c’est ce que je recommanderais de faire.

Voici les surcharges que vous déclareriez:

 public static Chart PopulateInto(List yAxis, List xAxis) { // Do stuff here } public static Chart PopulateInto(List yAxis, List xAxis) { // Do stuff here } 

De plus, si votre gestion de ces valeurs ne repose pas vraiment sur la qualité numérique de ces types, vous souhaitez simplement limiter les types que vous pouvez gérer, vous pouvez toujours déclarer votre méthode d’origine également, en privé , et appeler ceci. méthode de vos surcharges. Cela limiterait toujours votre code à autoriser publiquement uniquement les entiers int ou decimal , mais votre implémentation serait toujours générique. Sans savoir exactement ce que “faire des choses ici” implique, il est impossible de dire si cette option est viable ou non, mais voici le code de toute façon:

 public static Chart PopulateInto(List yAxis, List xAxis) { return PopulateInto(yAxis, xAxis); } public static Chart PopulateInto(List yAxis, List xAxis) { return PopulateInto(yAxis, xAxis); } private static Chart PopulateInto(List yAxis, List xAxis) where N : struct { // Do stuff here } 

Il n’est pas possible de contraindre un paramètre générique à un type de valeur spécifique.

Vous pouvez cependant le forcer à être un type valeur ou une struct en ajoutant where N : struct , mais c’est tout.

Il n’y a aucun moyen de faire cela avec une contrainte. Une autre approche cependant, en supposant que PopulateInto puisse fonctionner avec un N générique, consiste à rendre le kernel algorihtm générique et privé et à offrir 2 surcharges publiques prenant respectivement un int et un decimal . Cela va créer un effet similaire

 public static Chart PopulateInto( List yAxis, List xAxis) { return PopulateIntoCore(yAxis, xAxis); } public static Chart PopulateInto( List yAxis, List xAxis) { return PopulateIntoCore(yAxis, xAxis); } private static Chart PopulateIntoCore( List yAxis, List xAxis) where N : struct { ... } 

Comme Pieter l’a dit, vous ne pouvez pas utiliser une vérification au moment de la compilation. Cependant, vous pouvez effectuer les opérations suivantes au moment de l’exécution:

 if(!(typeof(N).equals(typeof(int32))) && !(typeof(N).equals(typeof(decimal)))) // do something