我有一个类 BaseEmailTemplate,用于格式化电子邮件,并且我想创建一个可以推翻默认值的派生类型。最初是我的基本构造函数-
public BaseEmailTemplate(Topic topic)
{
CreateAddresses(topic);
CreateSubject(topic);
CreateBody(topic);
}
... (Body/Addresses)
protected virtual void CreateSubject(Topic topic)
{
Subject = string.Format("Base boring format: {0}", topic.Name);
}
而在我的派生
public NewEmailTemplate(Topic topic) : Base (topic)
{
//Do other things
}
protected override void CreateSubject(Topic topic)
{
Subject = string.Format("New Topic: {0} - {1})", topic.Id, topic.Name);
}
当然这会导致这里讨论的错误:Virtual member call in a constructor
因此,绝对直言不讳——我不想在每个派生类型中调用相同的方法。另一方面,我需要能够更改任何/全部。我知道另一个基地有不同的地址子集,但正文和主题将是默认值。
必须调用所有三个方法,并且需要在每个派生的基础上提供更改其中任何一个方法的能力。
我的意思是每个人似乎都在说的事情是使用虚拟的意外后果似乎是我的确切意图..或者也许我太深并且专注于单一?
更新-澄清
我理解为什么构造函数中的虚拟成员不好,我很欣赏有关该主题的答案,尽管我的问题不是“为什么这不好?” “好吧,这很糟糕,但我看不出有什么能更好地满足我的需要,那我该怎么办?”
这是目前的实施方式
private void SendNewTopic(TopicDTO topicDto)
{
Topic topic = Mapper.Map<TopicDTO , Topic>(topicDto);
var newEmail = new NewEmailTemplate(topic);
SendEmail(newEmail); //Preexisting Template Reader infrastructure
//Logging.....
}
我正在处理一个孩子和孙子。我进来的地方只有 newemailtemplate,但我现在必须构建其他 4 个模板,但 90% 的代码是可重用的。这就是我选择创建 BaseEmailTemplate(Topic topic) 的原因。BaseTemplate 创建诸如主题和列表之类的内容以及 SendEmail 期望读取的其他内容。
NewEmailTemplate(Topic topic): BaseEmailTemplate(Topic topic): BaseTemplate, IEmailTempate
我宁愿不必要求任何关注我工作的人都必须知道
var newEmail = new NewEmailTemplate();
newEmail.Init(topic);
每次使用时都需要。没有它,该对象将无法使用。我以为有很多警告?