web-dev-qa-db-fra.com

Remplacer les constantes dans les classes dérivées en C #

En C #, une constante peut-elle être remplacée dans une classe dérivée? J'ai un groupe de classes qui ont toutes la même chose, à l'exception de certaines valeurs constantes. J'aimerais donc créer une classe de base définissant toutes les méthodes, puis simplement définir les constantes pertinentes dans les classes dérivées. Est-ce possible?

Je préfère ne pas simplement transmettre ces valeurs au constructeur de chaque objet, car j'aimerais bénéficier de la sécurité de type supplémentaire de plusieurs classes (car il n'est jamais logique d'interagir entre deux objets avec des constantes différentes).

32
Frankly

ce n'est pas une constante si vous voulez la remplacer;) essayez une propriété virtuelle en lecture seule (ou un scripteur protégé) ...

Propriété en lecture seule

public class MyClass {
    public virtual string MyConst { get {return "SOMETHING"; }}
}
...
public class MyDerived : MyClass {
    public override string MyConst { get { return "SOMETHINGELSE"; }}
}

Poseur protégé

public class MyClass {
    public string MyConst { get; protected set; }

    public MyClass() {
        MyConst = "SOMETHING";
    }
}

public class MyDerived : MyClass {
    public MyDerived() {
        MyConst = "SOMETHING ELSE";
    }
}
50
Tracker1

Malheureusement, les constantes ne peuvent pas être remplacées car elles ne sont pas des membres virtuels. Les identificateurs constants dans votre code sont remplacés par leurs valeurs littérales par le compilateur au moment de la compilation.

Je suggérerais que vous essayiez d'utiliser une propriété abstraite ou virtuelle pour ce que vous voudriez faire. Celles-ci sont virtuelles et peuvent donc (dans le cas d’une propriété abstraite) être écrasées dans le type dérivé.

29
Andrew Hare

Les constantes marquées avec const ne peuvent pas car elles sont remplacées par le compilateur au moment de la compilation.

Mais les champs statiques réguliers affectés à des valeurs constantes peuvent. J'ai eu un tel cas tout à l'heure:

    class Columns
    {
        public static int MaxFactCell = 7;
    };

    class Columns2 : Columns
    {
        static Columns2()
        {
            MaxFactCell = 13;
        }
    };

Si je venais de redéfinir le champ MaxFactCell dans la classe dérivée, le polymorphisme ne fonctionnerait pas: le code utilisant Columns2 en tant que Columns ne verrait pas la valeur de substitution.

Si vous devez restreindre l'accès en écriture (mais pas en lecture) au champ, l'utilisation de readonly interdirait sa redéfinition en Columns2. Faites-en une propriété à la place, c'est un peu plus de code:

    class Columns
    {
        static Columns()
        {
            MaxFactCell = 7;
        }            
        public static int MaxFactCell {get; protected set;};
    };

    class Columns2 : Columns
    {
        static Columns2()
        {
            MaxFactCell = 13;
        }
    };
3
ivan_pozdeev

Vous pouvez masquer la constante héritée dans une classe dérivée en déclarant la nouvelle constante new. Je ne suis pas sûr que ce soit une bonne pratique, cependant.

class A
{
    protected const int MyConst = 1;
}

class B : A
{
    new private const int MyConst = 2;
}
3
Jiří Skála

travailler hors réponse + Tracker1 mais mis à jour pour c # 6

public class MyClass {
    public virtual string MyConst =>"SOMETHING";
}
...
public class MyDerived : MyClass {
    public override string MyConst  =>"SOMETHING ELSE";
}
1
Marc Ziss

Vous pouvez forcer les classes dérivées à avoir une valeur pour une constante (bien, une propriété en lecture seule)

  • Créez une interface contenant une propriété en lecture seule.
  • Mettez cette interface sur la classe de base.

Exemple:

   public interface IHasConstant
   {
        string MyConst { get; }
   }
0
user1023602