Свойство, которое устанавливается только в защищенном конструкторе - PullRequest
0 голосов
/ 16 января 2020

У меня следующий класс, и мне интересно, правильно ли объявить ListOfItems как publi c с частным сеттером (с точки зрения лучшей практики OOP).

public abstract class Game
{
    public List<int> ListOfItemss { get; private set; }

    protected Game()
    {
    }

    protected Game(string gameInput)
    {
        ListOfItems = new List<int>();
        var gameParser = new GameParser();
        ListOfItems = gameParser.ParseGameInputString(gameInput);
    }

    public abstract int Bowl(int items);
}

Или я должен был сделать это через личное поле, например:

public abstract class Game
{
    private List<int> _listOfItems;

    public List<int> ListOfItemss 
    {
            get { return _listOfItems; }
            private set { _listOfItems = value; }
        }

    protected Game()
    {
    }

    protected Game(string gameInput)
    {
        ListOfItems = new List<int>();
        _listOfItems = new List<int>(); 
        var gameParser = new GameParser();
        _listOfItems = gameParser.ParseGameInputString(gameInput);
    }

    public abstract int Bowl(int items);
}

Обновлено на основе предложений: На основе в предложениях, приведенных ниже, вот код, который я думаю иметь в окончательной версии:

public abstract class Game
{
    public IReadOnlyCollection<int> ListOfItems { get; } = new List<int>();

    protected Game()
    {
    }

    protected Game(string gameInput)
    {
        var gameParser = new GameParser();
        ListOfItems = gameParser.ParseGameInputString(gameInput);
    }

    public abstract int Bowl(int items);
}

Ответы [ 3 ]

1 голос
/ 16 января 2020

Удалить установщик (который фактически делает его закрытым для конструкторов). Как указал Руфус, если вы не хотите, чтобы этот список изменялся вне класса, не выставляйте его как список. Кроме того, вы разрешаете создание Игры с нулевым ListOfItemss. Я бы заставил этот конструктор по умолчанию инициализировать список, как это делает другой c. Это делает их непротиворечивыми и позволяет избежать неприятных исключений с нулевыми ссылками, если вы пытаетесь получить доступ к game.ListOfItemss:

public abstract class Game
{
    public IEnumerable<int> ListOfItemss { get; } = new List<int>();

    protected Game()
    {
    }

    protected Game(string gameInput)
    {
        var gameParser = new GameParser();
        ListOfItemss = gameParser.ParseGameInputString(gameInput);
    }

    public abstract int Bowl(int items);
}
1 голос
/ 17 января 2020

Честно говоря, вы вообще не должны предоставлять внешний доступ к этому списку, это нарушает инкапсуляцию. Даже если свойство объявлено IReadOnlyList<int>, ничто не мешает кому-либо делать (List<int>)game.ListOfItemss. Частный сеттер или нет, на самом деле не имеет значения, если вы ограничиваете доступ к внутренностям. Если вам нужен внешний доступ к элементам вашего списка, откройте его с помощью контролируемых методов, таких как индексатор.

class Option0
{
    private readonly List<int> items;
    public int this[int index] => this.items[index];
}

Только ваш класс или, возможно, производные классы должны иметь доступ к этому списку.

С учетом сказанного, если вы хотите представить его в виде списка, доступного только для чтения, откройте его только для чтения.

class Option1
{
    private readonly List<int> items;
    public IReadOnlyList<int> Items => items.AsReadOnly();
    public Option1()
    {
        this.items = ...;
    }
}

class Option2
{
    private readonly List<int> items;
    public IReadOnlyList<int> Items { get; }
    public Option2()
    {
        this.items = ...;
        this.Items = this.items.AsReadOnly();
    }
}
1 голос
/ 16 января 2020

Вы можете просто удалить сеттер: public List<int> ListOfItemss { get; }

Редактировать: Как упоминалось в комментариях, вы можете получить больше информации о разнице между public List<int> ListOfItemss { get; } и public List<int> ListOfItemss { get; private set; } здесь

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