Исходные условия:
interface ISomeInterface
{
int SomeProperty { get; }
}
abstract class SomeClass
{
public abstract int AnotherProperty { get; }
}
class InheritedClass : SomeClass, ISomeInterface
{
public int SomeProperty { get; set; }
public override int AnotherProperty { get; set; }//Ошибка
}
Почему возникает ошибка при реализации абстрактного свойства в классе-наследнике, если добавить не заявленный в абстрактном свойстве геттер или сеттер? И почему нет ошибки для свойства объявленного в интерфейсе при тех же условиях?
С точки зрения интерфейсов, все правильно. Свойство представляет из себя пару методов. В интерфейсе, мы обязываем класс, реализующий наш интерфейс реализовать свойство с указанным аксессором, при этом не накладывая ни каких условий на наличие либо отсутствие второго аксессора.
С абстрактным классом немного сложнее. При реализации абстрактного свойства мы обязаны указать перед таким свойством ключевое слово override
, указывающее компилятору, что свойство было объявлено в базовом классе.
Синтаксис не позволяет указать override
для одного конкретного
аксессора, а только для всего свойства целиком, поэтому необъявленый в
базовом классе аксессор, тоже получает метку override
, но
переопределить его нельзя, так как он отсутствует в базовом классе.
Таким образом имеем противоречие: с одной стороны, мы пытаемся добавить новый метод в класс наследник, что не должно вызывать каких либо проблем, с другой, следуя синтаксису языка, пытаемся переопределить несуществующий метод, что вполне закономерно вызывает ошибку компиляции.
Вопрос почему сделано именно так, оставлю на совести разработчиков спецификации языка, в любом случае вряд ли это исправят в ближайшем будущем, если вообще исправят, поэтому проще считать это "особенностью" языка и просто знать о ней.
Как обойти проблему
Одно из возможных решений обхода данной "особенности":
abstract class SomeClass
{
public int AnotherProperty
{
get { return GetAnotherProperty(); }
}
protected abstract int GetAnotherProperty();
}
class InheritedClass : SomeClass
{
public new int AnotherProperty { get; set; }
protected override int GetAnotherProperty()
{
return AnotherProperty;
}
}
Другой вариант - вынести свойство в отдельный интерфейс и реализовать его в производном классе, тогда проблема решается вроде бы сама собой, но иногда такое решение не приемлемо, например если в абстрактном классе есть реализованные методы использующие данное свойство.
Ну и радикальный вариант - отказ от свойства как такового, и возврат к классическим методам GetXXX()
и SetXXX(value)
, этот вариант возможен абсолютно в любых условиях и не вызывает проблем ни в интерфейсах, ни в абстрактных классах, но ухудшает читабельность кода, хотя это конечно на любителя, в Java например, это единственный возможный вариант, если за последнее время в ней ни чего кардинально не поменялось.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Пытаюсь создать редактирование моделиВыскакивает ошибка:
Собственно вопрос заданЧасто на сайтах некоторые куки задаются не через Response, динамически при отработке javaScript