Здравствуйте, Angler, Вы писали:
A>Допустим имеется класс DataModel, у которого есть свойство типа List<Language>:
A>
A>class Language
A>{
A> //...
A>}
A>class DataModel
A>{
A> //...
A> public List<Language> languages
A> {
A> return m_languages;
A> }
A> //...
A>}
A>
A>Хочу запретить пользователся класса DataModel изменять коллекцию. В C++ просто бы вернул константную ссылку, а как быть в C#?
A>Спасибо.
A>ЗЫ С C# знаком мало, писал всё последнее время на C++, поэтому прошу не ругать за нубские вопросы))
public List<Language> languages
{
get { return m_languages; }
}
ST>class DataModel
ST>{
ST> publicICollection<Language> Languages
ST> {
ST> get
ST> {
ST> return m_languages.AsReadOnly();
ST> }
ST> }
ST>}
Это _очень_ плохо: во-первых, в чём смысл отдавать наружу "ICollection<Language>", а не "IList<Language>", ведь generic-ICollection имеет методы Add\Remove\Clear?
Во-вторых, свойство, которое каждый раз возвращает разный результат, выглядит подозрительно и не рекомендуется к использованию.
Правильный путь какой-то такой:
ST>class DataModel
ST>{
private IList<Language> list;
private ReadOnlyCollection<Language> readOnlyList;
/* где-то, где инициализируется list */
list = …;
readOnlyList = new ReadOnlyCollection<Language>(list);
// …
ST> public ReadOnlyCollection<Language> Languages
ST> {
ST> get
ST> {
ST> return readOnlyList;
ST> }
ST> }
ST>}
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Это _очень_ плохо: во-первых, в чём смысл отдавать наружу "ICollection<Language>", а не "IList<Language>", ведь generic-ICollection имеет методы Add\Remove\Clear?
Видать название ReadOnlyCollection вводит в заблуждение. С коллекциями в дотнете, к сожалению, не все гладко .
Здравствуйте, _FRED_, Вы писали:
_FR>Это _очень_ плохо: во-первых, в чём смысл отдавать наружу "ICollection<Language>", а не "IList<Language>", ведь generic-ICollection имеет методы Add\Remove\Clear?
Collection<T> provides 4 overridable methods; ClearItems, InsertItem, RemoveItem and SetItem, which allow a derived class to be notified when a collection has been modified. In contrast, List<T> provides none.
И там же приводят пример, где это может быть полезно.
Здравствуйте, Angler, Вы писали:
A>Хочу запретить пользователся класса DataModel изменять коллекцию. В C++ просто бы вернул константную ссылку, а как быть в C#?
Так вам надо запретить юзерам ДатыМодел подменять коллекцию(как объект) или запретить подменять ее отдельные элементы? Сорри, совершенно не в курсе как работает и что есть "константную ссылку" from C++, однако по звучанию как раз таки похоже вам первое нужно, а не второе, мм? Уточните, в опщем...
Здравствуйте, _FRED_, Вы писали:
_FR>Во-вторых, свойство, которое каждый раз возвращает разный результат, выглядит подозрительно и не рекомендуется к использованию.
Здравствуйте, dorofeevilya, Вы писали:
D>Почему? Чем это может грозить в данном случае?
В данном — это в каком?
А грозить может чем угодно — реализация свойств должна быть всегда максимально тривиальной и содержать минимальное количество логики. Вот человек не знает, что в вашем свойстве что-то такое создается и вызовет его пару сотен тысяч раз в цикле. Не говоря уж о том, что два вызова приведут к созданию двух объектов, у которых нет ссылочной эквивалентности.
Да и зачем так делать? Если это можно сделать *один* раз при создании вашего класса:
public MyType()
{
ReadOnlyList = (List = new List<T>()).AsReadOnly();
}
public List<T> List { get; private set; }
public ReadOnlyCollection<T> ReadOnlyList { get; private set; }
Здравствуйте, Smarty, Вы писали:
S>Здравствуйте, Angler, Вы писали:
A>>Хочу запретить пользователся класса DataModel изменять коллекцию. В C++ просто бы вернул константную ссылку, а как быть в C#?
S>Так вам надо запретить юзерам ДатыМодел подменять коллекцию(как объект) или запретить подменять ее отдельные элементы? Сорри, совершенно не в курсе как работает и что есть "константную ссылку" from C++, однако по звучанию как раз таки похоже вам первое нужно, а не второе, мм? Уточните, в опщем...
Мне необходимо, чтобы пользователи не могли изменять коллекцию, а также изменять её отдельные элементы. Но исходя из того, что все обьекты в моей коллекции не предоставляют методов/свойств для их изменения, то запрета изменения коллекции в данном случае вполне достаточно.
Здравствуйте, dorofeevilya, Вы писали:
_FR>>Во-вторых, свойство, которое каждый раз возвращает разный результат, выглядит подозрительно и не рекомендуется к использованию.
D>Почему? Чем это может грозить в данном случае?
var c1 = obj.Items;
var c2 = obj.Items;
Debug.Assert(c1 == c2, "c1 == c2");
// Для кого угодно станет большой неожиданностью, если утверждение выше нарушится, не правда ли?
Do use a method, rather than a property, in the following situations.
The operation returns a different result each time it is called, even if the parameters do not change. For example, the NewGuid method returns a different value each time it is called.
Всвязи с этим, DateTime.Now является примером неправильно использования свойства для возвращения значения.
Help will always be given at Hogwarts to those who ask for it.