Переопределение констант в производных классах в C # - PullRequest
33 голосов
/ 21 апреля 2009

В C # может ли константа быть переопределена в производном классе? У меня есть группа классов, которые все имеют одинаковые значения, поэтому я хотел бы создать базовый класс, который определяет все методы, а затем просто установить соответствующие константы в производных классах. Возможно ли это?

Я бы предпочел не просто передавать эти значения конструктору каждого объекта, поскольку я хотел бы, чтобы добавленная безопасность типов нескольких классов (поскольку никогда не имеет смысла взаимодействовать двум объектам с разными константами).

Ответы [ 6 ]

51 голосов
/ 21 апреля 2009

это не константа, если вы хотите переопределить ее;) попробуйте виртуальное свойство только для чтения (или защищенный установщик) ...

Свойство только для чтения

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

Защищенный сеттер

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

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

public class MyDerived : MyClass {
    public MyDerived() {
        MyConst = "SOMETHING ELSE";
    }
}
30 голосов
/ 21 апреля 2009

К сожалению, константы не могут быть переопределены, так как они не являются виртуальными членами. Идентификаторы констант в вашем коде заменяются их литеральными значениями компилятором во время компиляции.

Я бы предложил вам использовать абстрактное или виртуальное свойство для того, что вы хотели бы сделать. Они являются виртуальными и как таковые могут (должны быть, в случае абстрактного свойства) переопределяться в производном типе.

3 голосов
/ 12 февраля 2015

Вы можете скрыть унаследованную константу в производном классе, объявив новую константу new. Я не уверен, что это хорошая практика.

class A
{
    protected const int MyConst = 1;
}

class B : A
{
    new private const int MyConst = 2;
}
3 голосов
/ 23 января 2014

Константы, отмеченные const, не могут, поскольку они подставляются компилятором во время компиляции.

Но обычные статические поля, присвоенные постоянным значениям, могут. У меня был такой случай только сейчас:

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

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

Если бы я просто переопределил поле MaxFactCell в производном классе, полиморфизм не сработал бы: код, использующий Columns2 как Columns, не увидел бы переопределяющее значение.

Если вам нужно ограничить доступ для записи (но не для чтения) к полю, использование readonly запретит переопределять его в Columns2. Вместо этого сделайте это свойством, это немного больше кода:

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

    class Columns2 : Columns
    {
        static Columns2()
        {
            MaxFactCell = 13;
        }
    };
1 голос
/ 01 ноября 2016

Отработать ответ dten + Tracker1, но обновлено для c # 6

public class MyClass {
    public virtual string MyConst =>"SOMETHING";
}
...
public class MyDerived : MyClass {
    public override string MyConst  =>"SOMETHING ELSE";
}
0 голосов
/ 23 февраля 2017

Вы можете заставить производные классы иметь значение для константы (ну, свойство только для чтения)

  • Создание интерфейса, содержащего свойство только для чтения.
  • Поместите этот интерфейс в базовый класс.

Пример:

   public interface IHasConstant
   {
        string MyConst { get; }
   }
...