是否可以使用私有方法来避免构造函数中的虚拟成员?
AFAIK,人们一致认为从构造函数访问虚拟成员是一种危险的做法。 我们可以通过使用额外的步骤、方法来进行所需的初始化来克服这个问题吗?如下所示:
public class EntityAlpha {
public virtual string Value { get; protected set; }
public EntityAlpha(string value) {
Value = value;
}
}
替换为
public class EntityAlpha {
public virtual string Value { get; protected set; }
public EntityAlpha(string value) {
AssignValue(value);
}
private void AssignValue(string value) {
Value = value;
}
}
使用此附加方法的后果是什么?它仍然像在构造函数中使用虚拟成员一样危险还是最糟糕?!如何测试这个假设是否无害?
AFAIK, It's agreed that accessing virtual members from constructor is a dangerous practice.
Can we overcome this through using an additional step, a method, to make required initialization? like the following:
public class EntityAlpha {
public virtual string Value { get; protected set; }
public EntityAlpha(string value) {
Value = value;
}
}
to be replaced with
public class EntityAlpha {
public virtual string Value { get; protected set; }
public EntityAlpha(string value) {
AssignValue(value);
}
private void AssignValue(string value) {
Value = value;
}
}
What are consequences of using this additional method? Does it still dangerous like using virtual member in constructor or worst?! How to test if this assumption is not harmful?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您实际上遇到了同样的问题,只是现在代码更难以阅读。
关键是设计您的类,以便构造函数不会访问任何虚拟成员,即使通过其他方法间接访问也是如此。
You effectively have the same problem, only now the code is more difficult to read.
The key is designing your class so that the constructor won't reach any virtual members, even indirectly through other methods.
这不会改变任何东西,您仍然从构造函数调用虚拟方法,只是在中间放置了另一层。
That doesn't change anything, you're still calling a virtual method from the constructor, you've just put another layer in between.
这仍然同样危险;你所做的只是隐藏危险并混淆代码。
如果
Value
由实际数据字段(例如m_Value
)支持,您可以通过直接分配给m_Value
来防止出现问题。This is still just as dangerous; all you're doing is hiding the danger and obfuscating the code.
If
Value
is backed by an actual data field, saym_Value
, you can prevent the problem by assigning tom_Value
directly.它与从构造函数中使用它一样危险。它只会调用重写的实现。编译器可能会内联
AssignValue
函数,因此真正的代码看起来与之前的相同。It is as dangerous as using it from the constructor. It will simply call the overriden implementation. And compiler will probably inline the
AssignValue
function, so the real code will look the same as previous.我认为在这种情况下也会产生同样的效果。如果您要内联新方法,您会得到完全相同的代码,所以我猜它会编译得完全相同。如果退一步,你是否违反了里氏替换原则?看来您可能创建了一个不可取的层次结构。
I think it would have the same effect in this case. If you were to inline the new method you get the exact same code so I'm guessing it will compile exactly the same. If you take a step back are you breaking the Liskov Substitution Principle? It seems that you might have created a hierarchy that isn't advisable.