Переопределение констант в производных классах в С#
В С# можно ли переопределить константу в производном классе? У меня есть группа классов, у которых все равно есть некоторые постоянные значения, поэтому я хотел бы создать базовый класс, который определяет все методы, а затем просто устанавливает соответствующие константы в производных классах. Возможно ли это?
Я бы предпочел не просто передавать эти значения каждому конструктору объекта, как хотелось бы добавленную безопасность типов для нескольких классов (поскольку для взаимодействия двух объектов с разными константами никогда не имеет смысла).
Ответы
Ответ 1
это не константа, если вы хотите ее переопределить;) попробуйте виртуальное свойство только для чтения (или защищенный сеттер)...
Свойство только для чтения
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";
}
}
Ответ 2
К сожалению, константы нельзя переопределить, так как они не являются виртуальными членами. Константные идентификаторы в вашем коде заменяются литеральными значениями компилятором во время компиляции.
Я предлагаю вам попробовать использовать абстрактное или виртуальное свойство для того, что вы хотели бы сделать. Они являются виртуальными и как таковые могут (должны, в случае абстрактного свойства) быть переопределены в производном типе.
Ответ 3
Константы, помеченные знаком 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;
}
};
Ответ 4
Вы можете скрыть унаследованную константу в производном классе, объявив новую константу new
. Я не уверен, что это хорошая практика.
class A
{
protected const int MyConst = 1;
}
class B : A
{
new private const int MyConst = 2;
}
Ответ 5
Отработать ответ dten + Tracker1, но обновлен для С# 6
public class MyClass {
public virtual string MyConst =>"SOMETHING";
}
...
public class MyDerived : MyClass {
public override string MyConst =>"SOMETHING ELSE";
}
Ответ 6
Вы можете заставить производные классы иметь значение для константы (ну, свойство только для чтения)
- Создайте интерфейс, содержащий свойство только для чтения.
- Поместите этот интерфейс в базовый класс.
Пример:
public interface IHasConstant
{
string MyConst { get; }
}