3 votes

Génériques abstraits et liste de génériques abstraits

Je n'ai pas trouvé mon cas d'utilisation dans les questions existantes, alors j'y vais. J'ai une classe abstraite qui a des génériques comme ceci :

public abstract class aParameter<T>
{
    private T _parameter;

    public T Parameter
    {
        get { return _parameter;}
    }

    ...
}

Ensuite, j'ai mes classes "Type" comme ceci :

public class IntParameter : aParameter<Int32>
{
    public IntParameter(Int32 value)
    {
        _parameter = value;
    }
}

 public class TextParameter : aParameter<String>
{
    public TextParameter(String value)
    {
        _parameter = value;
    }
}

Maintenant, dans mon code d'application, je voudrais créer un dictionnaire avec la classe générique abstraite sans spécifier le type générique. Comme ceci :

...
private Dictionary<Int32, aParameter> _paramDict = new Dictionary<Int32, aParameter>();
...

Dans une version précédente, j'utilisais des interfaces au lieu de classes abstraites pour aParameter mais je voulais la migrer vers l'abstrait pour pouvoir simplifier mes classes de "Type" et ne pas répéter un code identique pour chaque "Type".

Des idées ?

EDITAR

J'ai oublié de mentionner qu'il fera partie d'une bibliothèque destinée à être distribuée au sein de l'entreprise, et que je dois donc vraiment sécuriser les types autorisés. Je ne peux pas autoriser seulement objects à introduire dans mon code.

6voto

Jon Egerton Points 16192

Vous aurez probablement toujours besoin de l'interface non générique (ou de la classe de base abstraite non générique comme le dit Brandon), à moins que vous ne vous contentiez de travailler avec des objets.

La raison en est que aParameter<String> n'est pas le même type que aParameter<int32> Vous ne pourrez donc pas les faire entrer dans un seul dictionnaire sans aide.

La méthode que je préfère pour contourner ce problème est de déclarer une interface non générique et de l'utiliser comme base pour le dictionnaire, puis de l'implémenter dans chacun de vos génériques typés, ainsi que dans une classe de base abstraite. De cette façon, vous pouvez hériter de la classe de base lorsque c'est possible, ou simplement implémenter l'interface si l'un de vos types doit hériter de quelque chose d'autre - vous obtenez une flexibilité maximale.

4voto

Brandon Moore Points 3772

Créez une classe de base abstraite non générique et faites en sorte que votre classe abstraite générique en hérite.

0voto

Steve Points 260

L'objectif des types génériques est (entre autres) de n'écrire qu'une seule fois un code qui peut être utilisé pour plusieurs types. Cependant, comme le C# est fortement typé, le compilateur doit savoir à quels types il a affaire dans la classe générique. C'est pourquoi vous devez spécifier le type du générique (c'est-à-dire le type entre crochets). Si vous ne spécifiez pas le type du générique, dans votre exemple, le compilateur ne connaîtrait pas le type de la propriété Parameter.

En fonction de ce que vous voulez en faire, plusieurs approches sont possibles :

  1. Utilisez un Dictionary<int, object> . Lors de la lecture des valeurs, vous pouvez utiliser un ensemble de if/elses pour vérifier le type spécifique de l'objet et le convertir dans le type approprié, par exemple

    if(obj.GetType() == typeof(TextParameter)) { TextParameter p = obj as TextParameter // Faire des choses } else if obj.GetType() == typeof(IntParameter)) { IntParameter p = obj as IntParameter // Faire quelque chose }

  2. Disposer de plusieurs dictionnaires. Dictionary<int, TextParameter> , Dictionary<int, IntParameter> etc.

  3. S'il y a des méthodes/propriétés dans aParameter qui ne sont pas dépendantes du type, déplacez-les vers une classe abstraite non générique de niveau inférieur. Cela pourrait vous donner au moins une partie de votre fonctionnalité sans avoir à recourir à des conversions de type.

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