看一下这个示例代码:
public class Comment
{
private Comment()
{ }
public Comment(string text, DateTime creationDate, string authorEmail)
{
Text = text;
CreationDate = creationDate;
AuthorEmail = authorEmail;
}
public virtual string Text { get; private set; }
public virtual DateTime CreationDate { get; set; }
public virtual string AuthorEmail { get; private set; }
}
我知道从构造函数调用虚拟成员函数被认为是不好的做法,但是在NHibernate中我需要虚拟属性来支持延迟加载。在这种情况下它被认为是好的吗?
答案 0 :(得分:5)
我很确定这很好,但如果你担心你总是可以在参数较少的构造函数调用之后分配属性。
答案 1 :(得分:2)
扩展Paco的答案:
在大多数情况下,它不会受到伤害。但是如果继承了类,则virtual允许覆盖属性get / set,因此行为不再完全封装和控制,因此理论上它可能会中断。 FxCop对此提出警告,因为这是一个潜在的问题。
FxCop的观点是帮助警告你潜在的问题。如果您知道从类中继承谁/什么,那么在构造函数中使用属性不是错误,但它不是正式的“最佳实践”。
所以,答案是,只要你控制了类的任何继承,它就没问题了。否则,请勿使用它并直接设置字段值。 (这意味着您不能使用C#3.0自动获取/设置属性 - 您必须自己编写包装字段的属性。)
旁注:就我个人而言,我的所有项目都是我们为客户托管的网站。因此,假设这个设置对于项目保持不变,那么必须权衡必须复制各种空值/参数检查。但是,在任何其他我不确定我们将完全控制项目和使用该类的情况下,我不会采用这种捷径。
答案 2 :(得分:1)
此示例中没有问题,但是在继承类并覆盖属性时可能会导致问题。通常,您可以更好地为虚拟属性创建字段。
答案 3 :(得分:1)
恕我直言,最佳做法是使用具有支持字段的属性:
public class Comment
{
private DateTime _creationDate;
private string _text;
private string _authorEmail;
private Comment() { }
public Comment(string text, DateTime creationDate, string authorEmail)
{
_text = text;
_creationDate = creationDate;
_authorEmail = authorEmail;
}
public virtual string Text
{
get { return _text; }
private set { _text = value; }
}
public virtual string AuthorEmail
{
get { return _authorEmail; }
private set { _authorEmail = value; }
}
public virtual DateTime CreationDate
{
get { return _creationDate; }
set { _creationDate = value; }
}
}
因此,您可以避免儿童课程出现问题,而且您再也看不到任何警告
答案 4 :(得分:0)
我知道如果你在构造函数中调用虚方法,FxCop会抱怨,但是我不知道FxCop说你是否在构造函数中调用虚拟属性...
我认为FxCop也会抱怨,因为属性被转换为IL中的方法。
您还可以将属性创建为“非虚拟”,并在NHIbernate中的“类映射”上指定“lazy = false”。 这不会影响集合的延迟加载行为。
(我一直这样做,因为我不喜欢我的基础设施(NHibernate)要求我将属性设置为虚拟。
我也不知道在NHibernate中使用动态代理的性能优势是否显着。)
答案 5 :(得分:0)
我认为,你不应该在构造函数中调用它。 您可以提供一个方法Initialize(),您可以在构造对象后调用它。
在Initialize()中,您可以调用所需的虚拟方法