我有一个类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);
}
当然,这会导致此处讨论的错误:构造函数中的虚拟成员调用
因此,请对此直言不讳-我不想在每个派生类型中都调用相同的方法。另一方面,我需要能够更改任何/全部。我知道另一个基准具有不同的地址子集,但是正文和主题将是默认的。
必须调用这三种方法,并且必须在每个派生基础上具有更改其中任何一种方法的能力。
我的意思是每个人似乎在说的事是使用虚拟的意外结果似乎是我的确切意图。或者也许我过于专注并过于专注?
更新-澄清
我理解为什么构造函数中的虚拟成员不好,我很欣赏关于该主题的答案,尽管我的问题不是“为什么这样不好?” 它的“好吧,这很糟糕,但是我看不出有什么能更好地满足我的需求,那我该怎么办?”
这是目前的实施方式
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(主题)的原因。BaseTemplate创建诸如Subject和List之类的内容以及SendEmail希望阅读的其他内容。
NewEmailTemplate(Topic topic): BaseEmailTemplate(Topic topic): BaseTemplate, IEmailTempate
我宁愿不必要求任何关注我工作的人都必须知道
var newEmail = new NewEmailTemplate();
newEmail.Init(topic);
每次使用时都是必需的。没有它,该对象将无法使用。我以为有很多警告吗?
C#Specification的[10.11]告诉我们,对象构造函数从基类开始到最继承的类依次运行。而规范的[10.6.3]告诉我们,它是在运行时执行的虚拟成员的最派生实现。
这意味着您Null Reference Exception
尝试从基础对象构造函数运行派生方法时,如果它访问由派生类初始化的项目,则可能会收到,因为派生对象尚未运行其构造函数。
实际上,Base方法的构造函数运行[10.11],并CreateSubject()
在构造函数完成并可以运行派生的构造函数之前尝试引用派生的方法,这使该方法产生了问题。
如前所述,在这种情况下,派生方法似乎仅依赖于作为参数传递的项目,并且可以很好地运行而不会出现问题。
请注意,这只是警告,并不是错误本身,而是指示在运行时可能发生错误。
如果从基类构造函数之外的任何其他上下文调用方法,则不会有问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句