考虑以下用c#.net 4.0编写的类(通常在nhibernate类中找到):
public class CandidateEntity : EntityBase
{
public virtual IList<GradeEntity> Grades { get; set; }
public CandidateEntity()
{
Grades = new List<GradeEntity>();
}
}
这一行得到了一个有根据的警告“构造函数中的虚拟成员调用”。 我应该在哪里初始化这个集合?
此致
答案 0 :(得分:11)
支持领域是一种方式。另一种是使用私人二传手。这在nHibernate中很有效。
public virtual IList<GradeEntity> Grades { get; private set; }
public CandidateEntity()
{
Grades = new List<GradeEntity>();
}
答案 1 :(得分:9)
使用支持字段并初始化构造函数中的支持字段。或者将课程密封。
private IList<GradeEntity> _grades
public virtual IList<GradeEntity> Grades
{
get { return _grades; }
set { _grades = value; }
}
public CandidatesEntity()
{
_grades = new List<GradeEntity>();
}
答案 2 :(得分:0)
如果您创建类sealed
,您也不会收到警告(因为如果您继承此类并覆盖该成员,则问题只是一个问题。)
OP评论后编辑:
啊,对。我通常只在处理继承的虚拟成员时遇到这种情况。 Yads的回答可能对你最有用。
请注意,您不必将整个属性设为虚拟。考虑一下:
List<Grade> Grades {
get { return _grades; }
set { _grades = value; OnGradesChanged(); }
protected virtual OnGradesChanged()
{ }
通常,您不希望以不同的方式在派生类中存储Grades
。您只需要在更改时进行更新。这样,您可以为派生类提供更多指导,并且您确信可以信任支持字段。
P.S。
您知道人们可以在没有课程的情况下编辑List<Grade>
吗?您应该考虑使用ObservableCollection
,其中包含在外部更改集合时的事件。在这种情况下,您只需要公开只读Grades
属性。
答案 3 :(得分:-1)
创建一个名为 OnInit 的类似的overridable(虚拟)方法,并在其中初始化Grade
,然后从构造函数中调用 OnInit 。
警告是通知您正在创建一个实施者难以覆盖的行为。