Синтаксис для виртуальных участников - PullRequest
8 голосов
/ 23 января 2011

Рассмотрим следующий класс, написанный на c # .net 4.0 (обычно находится в классе nhibernate):

public class CandidateEntity : EntityBase
{
    public virtual IList<GradeEntity> Grades { get; set; }

    public CandidateEntity()
    {
         Grades = new List<GradeEntity>(); 
    }
}

Эта строка получает обоснованное предупреждение «вызов виртуального члена в конструкторе».Где мне инициализировать эту коллекцию?

С уважением,

Ответы [ 4 ]

11 голосов
/ 16 июня 2011

Поле поддержки является односторонним.Другим является использование частного сеттера.Это хорошо работает в nHibernate.

public virtual IList<GradeEntity> Grades { get; private set; }

public CandidateEntity()
{
     Grades = new List<GradeEntity>();
}
9 голосов
/ 23 января 2011

Используйте поле поддержки и инициализируйте поле поддержки в конструкторе.Или сделайте класс запечатанным.

private IList<GradeEntity> _grades

public virtual IList<GradeEntity> Grades
{
   get { return _grades; }
   set { _grades = value; }
}

public CandidatesEntity()
{
   _grades = new List<GradeEntity>();
}
0 голосов
/ 23 января 2011

Если вы создадите класс sealed, вы также не получите предупреждение (поскольку проблема возникает только в том случае, если вы наследуете этот класс и переопределяете член).

Редактировать после комментария OP:

Ах, верно. Я обычно сталкиваюсь с этим только тогда, когда имею дело с унаследованными виртуальными членами. Ответ Яда, пожалуй, самый полезный для вас.

Пожалуйста, обратите внимание, что вам не нужно делать всю собственность виртуальной. Учтите это:

List<Grade> Grades { 
     get { return _grades; }
     set { _grades = value; OnGradesChanged(); }

protected virtual OnGradesChanged()
{ }

Обычно вы не хотите хранить Grades другим способом в производном классе. Вам просто нужно сделать некоторые обновления, когда они меняются. Таким образом, вы дадите дополнительные указания производному классу и уверены, что можете доверять вспомогательному полю.

P.S. Вы знаете, что люди могут редактировать List<Grade>, даже если ваши классы его не видят? Вы должны рассмотреть возможность использования ObservableCollection, который включает в себя событие, когда коллекция изменяется внешне. В этом случае вам нужно только предоставить доступное только для чтения свойство Grades.

0 голосов
/ 23 января 2011

Создайте переопределяемый (виртуальный) метод с именем OnInit или чем-то подобным и инициализируйте там Grade, затем вызовите OnInit из конструктора.

Предупреждениездесь, чтобы сообщить вам, что вы создаете поведение, которое будет трудно переопределить разработчикам.

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