【发布时间】:2014-04-30 23:39:48
【问题描述】:
我有几个类,其中一些是抽象的,我希望该方法的基类版本调用同一类中另一个方法的最派生版本,然后它会沿着链向上运行并执行“完整”方法的工作。我之所以有基础方法和派生方法,是因为不同级别对信息的访问方式不同。如果“订单”对象为 null,我不想在尝试获取信息之前测试 null。结果是一系列“级联”类,每个派生版本的方法调用基方法,然后在基方法正在执行的操作上构建以实现其目标。
public abstract class EmailTemplates
{
....
protected virtual string ReplaceVariables(KeyValuePair<string, string> namevalue, string body)
{
// This builds an email body
protected void BuildBody()
{
if(NamesValues != null)
{
foreach (KeyValuePair<string, string> namevalue in NamesValues)
{
// This gives back eg "order details"
string subsectionName;
// Test if this value is a subsection
// If subsection not in the list, keep unchanged
if (Subsections.TryGetValue(namevalue.Key, out subsectionName))
{
// This retrieves the subsection details
this.emailBody = this.emailBody.Replace(namevalue.Value, GetSubsection(subsectionName, namevalue.Value));
}
// This is a regular variable not a subsection
else
{
this.emailBody = ReplaceVariables(namevalue, this.emailBody);
}
}
}
}
}
protected virtual string ReplaceVariables(KeyValuePair<string, string> namevalue, string body)
{
switch(namevalue.Key)
{
case "url":
body = body.Replace(namevalue.Value, Url);
break;
case "username":
body = body.Replace(namevalue.Value, HttpContext.Current.User.Identity.Name);
break;
}
return body;
}
....
}
public abstract class CustomerEmailTemplates : EmailTemplates
{
...
protected new string ReplaceVariables(KeyValuePair<string, string> namevalue, string body)
{
body = base.ReplaceVariables(namevalue, body);
switch (namevalue.Key)
{
case "forename":
// If they don't have a profile, just use the username
if ((Profile != null) && (Profile.IsAnonymous || Profile.DeliveryAddress1.FirstName == null || Profile.DeliveryAddress1.FirstName == ""))
{
body = body.Replace(namevalue.Value, Username);
}
// If user is changing their password, etc.
else if (Profile != null)
{
body = body.Replace(namevalue.Value, Profile.DeliveryAddress1.FirstName);
}
// To display template to admin don't replace anything
break;
case "surname":
// If they don't have a profile, just use nothing as username will already be there
if ((Profile != null) && (Profile.IsAnonymous || Profile.DeliveryAddress1.LastName == null || Profile.DeliveryAddress1.LastName == ""))
{
body = body.Replace(namevalue.Value, "");
}
else if (Profile != null)
{
body = body.Replace(namevalue.Value, Profile.DeliveryAddress1.LastName);
}
// To display template to admin don't replace anything
break;
}
return body;
}
...
}
public class OrderEmailTemplates : CustomerEmailTemplates
{
...
protected new string ReplaceVariables(KeyValuePair<string, string> namevalue, string body)
{
body = base.ReplaceVariables(namevalue, body);
switch (namevalue.Key)
{
case "customerEmail":
body = body.Replace(namevalue.Value, Order.CustomerEmail);
break;
case "orderID":
body = body.Replace(namevalue.Value, Order.ID.ToString());
break;
....
}
...
}
对于代码转储,我很抱歉,但我不确定如何使它(大大)小。我希望发生的事情是让BuildEmailBody() 下到最后一个调用OrderEmailTemplates.ReplaceVariables() 的派生类并返回基类,但现在它只是调用EmailTemplates.ReplaceVariables() 而不是替换所有值我想要它。
【问题讨论】:
-
你可以创建一个虚方法,例如在基类 Moo make abstract Foo() { FooExt();并在继承 Moo 的类中为 FooExt() 实现(如果需要.. 虚拟)
标签: c# inheritance derived-class base-class