Предоставление структуры данных массива с использованием свойств - PullRequest
2 голосов
/ 13 марта 2009

Типично представить внутренние структуры данных как свойства вашему бизнес-классу. Но когда нам нужно представить структуры, похожие на массивы (например, правила List ), мы можем столкнуться с проблемой неправильного использования (как в варианте 1).

Предлагается выставить клон таких структур данных как свойства, чтобы не нарушать внутреннюю структуру.

Есть ли у кого-нибудь хорошо продуманное решение для этого?

public class Rule 
{
}

public class RulesManager 
{
    List<Rule> rules = new List<Rule>();

    public List<Rule> Rules
    {
        get { return rules; }
        set { rules = value; }
    }

    public void Add(Rule r)
    {
        rules.Add(r);
        // Do something else after add;
    }

    public void Delete(Rule r) 
    {
        rules.Remove(r);
        // Do something else after delete;
    }
}
public class CallingCode 
{
    public static void Main() 
    {
        RulesManager r = new RulesManager();
        // Option 1            
        r.Rules.Add(new Rule());
        // Option 2 
        r.Add(new Rule());
    }
}

Ответы [ 5 ]

2 голосов
/ 13 марта 2009

Вместо возврата Clone вы можете вернуть версию rules, доступную только для чтения, используя rules.AsReadOnly().

public IList<Rule> Rules
{
  get { return rules.AsReadOnly(); }
// set { rules = value; -- should not be allowed to set if read only!
}

Обратите внимание на IList.

0 голосов
/ 13 марта 2009

Основной обходной путь - использовать метод List<T>.AsReadOnly(), который обернет список вокруг ReadOnlyCollection, чтобы заблокировать любой доступ «записи». Конечно, вам придется сделать сеттер приватным, иначе это не имеет смысла ...

Другой альтернативой может быть создание собственного IList, который будет предупреждать вас в случае доступа «запись» и позволит вам выполнять свою бизнес-логику.

0 голосов
/ 13 марта 2009

Проверьте ReadOnlyCollection и AsReadOnly () Список метода.

0 голосов
/ 13 марта 2009

Я думаю, что довольно часто выставлять IList как свойство, но я предпочитаю выставлять только явные функции Add / Delete. Вы также можете рассмотреть возможность реализации одного из интерфейсов коллекций в своем классе (например, IList), если вы разрабатываете что-то более каркасное.

Вместо:

public List<Rule> Rules
{
    get { return rules; }
    set { rules = value; }
}

Я предпочитаю реализовать IEnumerable<T> и индексатор для класса, чтобы я мог контролировать, что происходит со списком.

0 голосов
/ 13 марта 2009

Вместо возврата списка вы можете вернуть IEnumerable. IEnumerable позволяет пользователю выполнять итерацию по коллекции, но не позволяет пользователю легко ее изменять.

В качестве альтернативы вы можете вернуть массив вместо списка. Это создаст копию списка, который пользователь не сможет легко изменить.

Наконец, вы должны знать, что пользователь может также изменить содержимое коллекции. Это может быть то, что вы хотите, но вы также можете вернуть копии ваших предметов.

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