Отдельные объявления getter и setter - PullRequest
1 голос
/ 24 марта 2019

Как я могу отдельно объявить получатель и установщик для свойства?

Например, скажем, я хочу создать следующую иерархию:

interface IReadOnlyFoo
{
    string Value { get; }
}

interface IFoo : IReadOnlyFoo
{
    string Value { set; }
}

class BasicFoo : IFoo
{
    string Value { get; set; }
}

Компилятор компанируется, потому что IFoo.Value скрывает IReadOnlyFoo.Value, что я не хочу делать.Я хочу «объединить» объявления получения и установки.

Я посмотрел, как .NET Framwork объявляет интерфейсы IReadOnlyList и IList, но это делается по-другому.

Как я могу достичь того, что хочу сделать?Могу ли я сделать это с помощью свойства или мне действительно нужно вместо этого создавать отдельные методы GetValue() и SetValue()?

Ответы [ 3 ]

3 голосов
/ 24 марта 2019

Когда вы изменяете определение интерфейса на

interface IReadOnlyFoo
{
    string Value { get;  }
}

interface IReadWriteFoo
{
    string Value { get; set; }
}

class BasicFoo : IFoo, IReadOnlyFoo
{
    public string Value { get; set; }
}

это должно работать.

2 голосов
/ 24 марта 2019

Когда вы реализуете интерфейс, два члена будут объединены, так как у вас нет метода get в IFoo.Value.

    interface IReadOnlyFoo
    {
        string Value { get; }
    }

    interface IFoo : IReadOnlyFoo
    {
        new string Value { set; }
    }

    class BasicFoo : IFoo
    {
       public string Value { get;  set; }
    }

Пока вы используете неявные реализации для интерфейсов, они будут вести себя так, как вы и планировали. с другой стороны, если вы хотите иметь два разных поведения для членов интерфейса, то вы хотите использовать явные реализации. Вы можете найти пример здесь
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/how-to-explicitly-implement-members-of-two-interfaces

0 голосов
/ 24 марта 2019

Все, что вам нужно изменить в своем коде, это добавить геттер к свойству Value в интерфейсе IFoo.

Семантически говоря, IFoo - это особый тип IReadOnlyFoo, которыйдобавляет еще одну возможность к своему базовому типу (установщик свойства Value).
Это точное определение наследования в объектно-ориентированном программировании - дочерний тип является более конкретной версией своего базового типа и добавляет возможности кit.

interface IReadOnlyFoo
{
    string Value { get;  }
}

interface IFoo : IReadOnlyFoo
{
    new string Value { get; set; }
}

class BasicFoo : IFoo
{
    public string Value { get; set; }
}

Этот код является абсолютно действительным и даст вам именно то, что вы ищете.

Таким образом, если у вас есть ссылка типа IReadOnlyFoo на экземпляриз BasicFoo, свойство Value действительно доступно только для чтения, но если ваш ссылочный тип IFoo, это свойство чтения / записи.

Вы можете увидеть живую демонстрацию на rextester.

...