Я хочу сделать это:
interface IBase
{
string Property1 { get; }
}
interface IInherited : IBase
{
string Property1 { get; set; }
}
Чтобы у IInherited
было унаследованное свойство Свойство Property1
] с добавленной функциональностью, позволяющей установить
.
Возможно ли это? Какой синтаксис?
РЕДАКТИРОВАТЬ: обратите внимание, я выделил слово «унаследовано» жирным шрифтом. Я спрашиваю конкретно о наследовании имущества, а не о том, чтобы скрыть его за новым.
Скрытие участника нарушает принцип замены Лискова, и в значительной степени этого делать не следует никогда. Скрывая этот член, вы вводите ошибку, которую очень сложно обнаружить, поскольку будут происходить 2 разных результата в зависимости от того, приводите ли вы объект как IBase1 или приводите его к IBase.
http: //en.wikipedia.org / wiki / Liskov_substitution_principle
Не явно, нет. У вас есть два варианта:
public interface IBase
{
string Property1 { get; }
}
public interface IInherited : IBase
{
void SetProperty1(string value);
}
Или вы можете просто отключить предупреждение компилятора с помощью ключевого слова new
:
public interface IBase
{
string Property1 { get; }
}
public interface IInherited : IBase
{
new string Property1 { get; set; }
}
Если вы не реализуете IInherited.Property1
явно, IBase
] будет автоматически связываться с вашей устанавливаемой реализацией.
К сожалению, нет - свойства не могут быть расширены как таковые. Однако вы можете просто скрыть свойство с помощью new:
interface IInherited : IBase
{
// The new is actually unnecessary (you get warnings though), hiding is automatic
new string Property1 { get; set; }
}
Или вы можете создать свои собственные методы получения и установки, которые можно переопределить (старый добрый стиль Java):
interface IBase
{
string GetProperty1();
}
interface IInherited : IBase
{
void SetProperty1(string str);
}
Свойства фактически преобразуются в методы получения и установки компилятором.
Ваш код все равно должен работать ... он просто создает предупреждение компилятора из-за того, что скрывает Property1. Чтобы убрать это предупреждение, отметьте Свойство 1 в II, унаследованное с новым префиксом
Вы можете либо пометить свойство ключевым словом "new", либо пропустить наследование:
public interface IBase
{
string Property1 { get; }
}
public interface IInherited : IBase
{
new string Property1 { get; set; }
}
Или:
public interface IBase
{
string Property1 { get; }
}
public interface IInherited
{
string Property1 { get; set; }
}
В любом случае, это должно сработать:
public class SomeClass : IInherited, IBase
{
public string Property1
{
get
{
// ...
}
set
{
// ...
}
}
}
Вы можете хорошенько подумать, прежде чем делать цепочку наследования для ваших интерфейсов. Кто какой интерфейс будет смотреть? Придется ли вам приводить к IInherited при передаче IBase? Если да, можете ли вы быть уверены, что сможете выполнить это приведение (если вы разрешите классы, созданные пользователем, тогда ответ будет отрицательным)? Этот вид наследования может серьезно повредить (повторному) удобству использования, если вы не будете осторожны.
Если тот факт, что единственный способ сделать это - использовать ключевое слово new
, беспокоит вас, то, на мой взгляд, вы неправильно думаете об интерфейсах.
Конечно, вы можете сказать, что IInherited
"наследуется от" IBase
; но что это на самом деле означает? Это интерфейсы; они устанавливают кодовые контракты. Скрывая свойство IBase.Property1
с помощью new string Property1 { get; set; }
, вы не затеняете никакой функциональности. Таким образом, традиционная причина, по которой многие разработчики считают скрытие "плохой" вещью - что оно нарушает полиморфизм - в данном случае не имеет значения.
Спросите себя: что действительно важно, когда речь идет об интерфейсах? Они дают гарантию ответа на определенные вызовы методов, верно?
Итак, даны следующие два интерфейса:
interface IBase
{
string Property1 { get; }
}
interface IInherited : IBase
{
new string Property1 { set; }
}
IBase
, вы можете прочитать его свойство Property1
. IInherited
, вы можете читать его свойство Property1
(как и в случае реализации IBase
), а также писать в него. Опять же, здесь нет ничего проблематичного.