Consider the following class written in c# .net 4.0 (typically found in a nhibernate class):
public class CandidateEntity : EntityBase
{
public virtual IList<GradeEntity> Grades { get; set; }
public CandidateEntity()
{
Grades = new List<GradeEntity>();
}
}
This line gets a well founded warning "virtual member cal开发者_JAVA百科l in the constructor". Where shall I initialize this collection ?
Regards,
The backing field is one way. Another is to use a private setter. This works well in nHibernate.
public virtual IList<GradeEntity> Grades { get; private set; }
public CandidateEntity()
{
Grades = new List<GradeEntity>();
}
Use a backing field and initialize the backing field in the constructor. Alternatively make the class sealed.
private IList<GradeEntity> _grades
public virtual IList<GradeEntity> Grades
{
get { return _grades; }
set { _grades = value; }
}
public CandidatesEntity()
{
_grades = new List<GradeEntity>();
}
If you make the class sealed
you won't get the warning either (because the issue is only an issue if you inherit this class and override the member).
Edit after OP comment:
Ah, right. I usually encounter this only when I'm dealing with inherited virtual members. Yads' answer is probably the most useful for you.
Please also note you don't have to make the entire property virtual. Consider this:
List<Grade> Grades {
get { return _grades; }
set { _grades = value; OnGradesChanged(); }
protected virtual OnGradesChanged()
{ }
Usually, you don't want to store the Grades
in a different way in the derived class. You just need to do some updating when it changes. This way, you provide more guidance to the derived class, and you are sure that you can trust the backing field.
P.S.
You are aware that people can edit the List<Grade>
without your classes seeing it? You should consider using ObservableCollection
which includes an event when the collection is changed externally. In that case, you only need to expose a readonly Grades
property.
Create an overridable (virtual) method called OnInit or something similar and initialize Grade
in there, then call OnInit from the constructor.
The warning is there to inform you that you are creating a behavior that will be difficult for implementers to override.
精彩评论