Константная ссылка?
От: Angler Россия  
Дата: 24.06.09 12:51
Оценка:
Допустим имеется класс DataModel, у которого есть свойство типа List<Language>:


class Language 
{
  //...
}

class DataModel
{
  //...
  public List<Language> languages
  {
    return m_languages;
  }
  //...
}



Хочу запретить пользователся класса DataModel изменять коллекцию. В C++ просто бы вернул константную ссылку, а как быть в C#?

Спасибо.

ЗЫ С C# знаком мало, писал всё последнее время на C++, поэтому прошу не ругать за нубские вопросы))
Re: Константная ссылка?
От: Аноним  
Дата: 24.06.09 12:54
Оценка: 4 (1)
Здравствуйте, 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#?


Используй ReadonlyCollection<Language>.
Re: Константная ссылка?
От: Sorantis Швеция  
Дата: 24.06.09 12:56
Оценка:
Здравствуйте, 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; }
  }
As long as there is life, there is hope
Re: Константная ссылка?
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 24.06.09 12:57
Оценка: 4 (1)
Здравствуйте, 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>




class DataModel
{
  public ICollection<Language> Languages
  {
    get
    {
      return m_languages.AsReadOnly();
    }
  }
}
Re[2]: Константная ссылка?
От: _FRED_ Черногория
Дата: 24.06.09 13:13
Оценка: 16 (2) +2
Здравствуйте, SergeyT., Вы писали:

ST>class DataModel
ST>{
ST>  public ICollection<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.
Re[3]: Константная ссылка?
От: jenyavb  
Дата: 24.06.09 14:09
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Это _очень_ плохо: во-первых, в чём смысл отдавать наружу "ICollection<Language>", а не "IList<Language>", ведь generic-ICollection имеет методы Add\Remove\Clear?

Видать название ReadOnlyCollection вводит в заблуждение. С коллекциями в дотнете, к сожалению, не все гладко .
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[3]: Константная ссылка?
От: User239 Россия  
Дата: 24.06.09 15:27
Оценка:
Здравствуйте, _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.

И там же приводят пример, где это может быть полезно.
Re: Константная ссылка?
От: Smarty Россия  
Дата: 24.06.09 16:21
Оценка:
Здравствуйте, Angler, Вы писали:

A>Хочу запретить пользователся класса DataModel изменять коллекцию. В C++ просто бы вернул константную ссылку, а как быть в C#?


Так вам надо запретить юзерам ДатыМодел подменять коллекцию(как объект) или запретить подменять ее отдельные элементы? Сорри, совершенно не в курсе как работает и что есть "константную ссылку" from C++, однако по звучанию как раз таки похоже вам первое нужно, а не второе, мм? Уточните, в опщем...
Re[3]: Константная ссылка?
От: dorofeevilya Россия  
Дата: 24.06.09 17:40
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Во-вторых, свойство, которое каждый раз возвращает разный результат, выглядит подозрительно и не рекомендуется к использованию.


Почему? Чем это может грозить в данном случае?
Re[4]: Константная ссылка?
От: Воронков Василий Россия  
Дата: 24.06.09 20:35
Оценка: 2 (1) +1
Здравствуйте, dorofeevilya, Вы писали:

D>Почему? Чем это может грозить в данном случае?


В данном — это в каком?
А грозить может чем угодно — реализация свойств должна быть всегда максимально тривиальной и содержать минимальное количество логики. Вот человек не знает, что в вашем свойстве что-то такое создается и вызовет его пару сотен тысяч раз в цикле. Не говоря уж о том, что два вызова приведут к созданию двух объектов, у которых нет ссылочной эквивалентности.
Да и зачем так делать? Если это можно сделать *один* раз при создании вашего класса:

public MyType()
{
  ReadOnlyList = (List = new List<T>()).AsReadOnly();
}

public List<T> List { get; private set; }
public ReadOnlyCollection<T> ReadOnlyList { get; private set; }
Re[2]: Константная ссылка?
От: Angler Россия  
Дата: 25.06.09 07:24
Оценка:
Здравствуйте, Smarty, Вы писали:

S>Здравствуйте, Angler, Вы писали:


A>>Хочу запретить пользователся класса DataModel изменять коллекцию. В C++ просто бы вернул константную ссылку, а как быть в C#?


S>Так вам надо запретить юзерам ДатыМодел подменять коллекцию(как объект) или запретить подменять ее отдельные элементы? Сорри, совершенно не в курсе как работает и что есть "константную ссылку" from C++, однако по звучанию как раз таки похоже вам первое нужно, а не второе, мм? Уточните, в опщем...


Мне необходимо, чтобы пользователи не могли изменять коллекцию, а также изменять её отдельные элементы. Но исходя из того, что все обьекты в моей коллекции не предоставляют методов/свойств для их изменения, то запрета изменения коллекции в данном случае вполне достаточно.

Всем спасибо.
Re[4]: Константная ссылка?
От: _FRED_ Черногория
Дата: 25.06.09 09:34
Оценка: 2 (1)
Здравствуйте, dorofeevilya, Вы писали:

_FR>>Во-вторых, свойство, которое каждый раз возвращает разный результат, выглядит подозрительно и не рекомендуется к использованию.


D>Почему? Чем это может грозить в данном случае?


var c1 = obj.Items;
var c2 = obj.Items;
Debug.Assert(c1 == c2, "c1 == c2");
// Для кого угодно станет большой неожиданностью, если утверждение выше нарушится, не правда ли?


А, вообще, читать Design Guidelines for Developing Class Libraries: Choosing Between Properties and Methods

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.
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.