Добавить 'set' в свойства интерфейса в C # - PullRequest
17 голосов
/ 08 марта 2009

Я стремлюсь «расширить» интерфейс, предоставив набор средств доступа к свойствам в этом интерфейсе. Интерфейс выглядит примерно так:

interface IUser
{
    string UserName
    {
        get;
    }
}

Я хочу что-то вроде этого:

interface IMutableUser : IUser
{
    string UserName
    {
        get;
        set;
    }
}

Мне нужно наследство. Я не могу скопировать тело IUser в IMutableUser и добавить установленные методы доступа.

Возможно ли это в C #? Если так, как это может быть достигнуто?

Ответы [ 3 ]

14 голосов
/ 08 марта 2009

Я не вижу причин, почему то, что вы опубликовали, не должно работать? Просто сделал быстрый тест, и он хорошо компилируется, но выдает предупреждение о сокрытии. Это можно исправить, добавив новое ключевое слово, например:

public interface IMutableUser : IUser
{
    new string Username { get; set; }
}

Альтернативой может быть добавление явных методов набора; например:

public interface IMutableUser : IUser
{
    void SetUsername(string value);
}

Конечно, я бы предпочел использовать сеттеры, но если это невозможно, я думаю, вы делаете то, что должны.

9 голосов
/ 08 марта 2009

Вы можете использовать абстрактный класс:

interface IUser
{
    string UserName
    {
        get;
    }
}

abstract class MutableUser : IUser
{
    public virtual string UserName
    {
        get;
        set;
    }
}

Другая возможность заключается в следующем:

interface IUser
{
    string UserName
    {
        get;
    }
}

interface IMutableUser
{
    string UserName
    {
        get;
        set;
    }
}

class User : IUser, IMutableUser
{
    public string UserName { get; set; }
}
8 голосов
/ 08 марта 2009

Вы можете «переопределить» свойства в интерфейсе, явно реализовав интерфейсы. Вероятно, ответ Криса - это все, что вам нужно для описанного вами сценария, но рассмотрим немного более сложный сценарий, когда вам нужен метод получения / установки в вашем классе, но интерфейс определяет только метод получения. Вы можете обойти это, выполнив следующие действия:

public class MyUser : IUser
{

    IUser.MyProperty { get { return "something"; } }

    public MyProperty { get; set; }

}

Путем явной реализации IUser.MyProperty вы удовлетворяете контракту. Однако, предоставляя public MyProperty, API для вашего объекта никогда не будет показывать явную версию интерфейса и всегда будет использовать MyProperty с get / set.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...