Подтвердить что ты не робот

С#: наследование наследования геттеров/сеттеров

У меня есть набор интерфейсов, которые используются в тесном взаимодействии с определенным изменчивым объектом.

Многим пользователям объекта требуется только возможность считывать значения из объекта, а затем только несколько свойств. Чтобы избежать загрязнения пространства имен (проще intellisense) и чтобы понять смысл использования, я хотел бы иметь небольшой базовый интерфейс, который предоставляет только несколько "ключевых" свойств только для чтения.

Однако почти все реализации будут поддерживать полный интерфейс, который включает в себя изменчивость.

К сожалению, я столкнулся с дорожным блоком, выражающим эту концепцию в С#:

interface IBasicProps {
   public int Priority { get; }
   public string Name {get;}
   //... whatever
}

interface IBasicPropsWriteable:IBasicProps  {
   public int Priority { set; } //warning CS0108: [...] hides inherited member [...]
   public string Name { set; }
   //... whatever
}

Я, конечно же, не собирался скрывать каких-либо членов, так что нехорошо!

Конечно, я могу решить это, используя методы просто отлично, но какой правильный выбор? Я бы хотел, чтобы "основной" интерфейс был как можно мал, даже если разделение интерфейсов не имеет никакой цели, кроме передачи намерений. С раздельными интерфейсами просто очевидно, какие методы не собираются делать никакого обновления, и это делает код написания немного понятнее (не говоря уже о том, что для простого простого случая достаточно простых статических одноэлементных прошивок достаточно простого).

Я бы хотел избежать любых абстрактных классов и тому подобного; они делают повторное выполнение или быстрые одноцелевые прокладки все более сложными и труднодоступными.

Итак, идеи?

4b9b3361

Ответ 1

Метод, скрывающийся в интерфейсе, не так близок; Я бы пошел с чем-то вроде:

interface IBasicProps {
   int Priority { get; }
   string Name {get;}
   //... whatever
}

interface IBasicPropsWriteable:IBasicProps  {
   new int Priority { get; set; }
   new string Name { get; set; }
   //... whatever
}
class Foo : IBasicPropsWriteable {
    public int Priority {get;set;}
    public string Name {get;set;}
/* optional
    int IBasicProps.Priority {get {return Priority;}}
    string IBasicProps.Name {get {return Name;}}
*/
}

Ответ 2

Если ваша цель состоит в том, чтобы сделать ее более ясной, если разрешено чтение или запись, я бы использовал отдельные методы getter и setter, а не свойства.

interface IBasicProps {
   int GetPriority();
   string GetName();
   //... whatever
}

interface IBasicPropsWriteable:IBasicProps  {
   void SetPriority(int priority);
   void SetName(string name);
   //... whatever
}

Ответ 3

Одним из способов может быть просто пропустить наследование интерфейсов. Сделайте один интерфейс только для чтения и один только для записи и при необходимости выполните:

interface IBasicPropsReadable {
   int Priority { get; }
   string Name { get; }
}

interface IBasicPropsWriteable  {
   int Priority { set; }
   string Name { set; }
}

class SomeClassReadWrite : IBasicPropsReadable, IBasicPropsWriteable {
    int Priority { get; set; }
    string Name { get; set; }
}

class SomeClassReadOnly : IBasicPropsReadable {
    int Priority { get; }
    string Name { get; }
}

Ответ 4

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

public interface IBasicProps
{
   int Priority { get; }
   string Name {get;}
   //... whatever
}

public interface IBasicPropsWriteable
{
   int Priority { get; set; }
   string Name { get; set; }
   //... whatever
}

public class Foo : IBasicProps, IBasicPropsWriteable
{
   public int Priority { get; set; }
   public string Name { get; set; }

   // whatever
}

Если вам действительно нужна оптимизация, вы можете создать еще один интерфейс, который вытекает из обоих, и ваши классы реализуют это.

public interface IBasicPropsAll : IBasicProps, IBasicPropsWriteable  { }

public class Foo : IBasicPropsAll
{
   public int Priority { get; set; }
   public string Name { get; set; }

   // whatever
}