2009-03-13 3 views
2

Характерно, чтобы внутренние структуры данных отображались как свойства вашего бизнес-класса. Но когда нам приходится выставлять массивные структуры (например, правила < Правила >), мы можем столкнуться с проблемой неправильного использования (как в Варианте 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()); 
    } 
} 

ответ

2

Вместо возвращения 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

Но мое определение изменится со списка на ReadOnlyCollection , rt? – NileshChauhan

+0

Когда-либо слышал о типе литья? :-) Я уточню ... –

0

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

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

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

0

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

Вместо:

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

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

0

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

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