我可以从基类调用派生方法吗?

本文关键字:方法 派生 调用 基类 我可以 | 更新日期: 2023-09-27 17:52:37

我有几个类,其中一些是抽象的,我希望方法的基类版本调用同一类中另一个方法的最派生版本,然后在链上工作,并完成方法的"完整"工作。我之所以有基方法和派生方法,是因为不同的层次对信息的访问方式不同。如果一个'Order'对象是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(),而不是替换我想要的所有值。

我可以从基类调用派生方法吗?

    虚拟方法
  1. 覆盖
  2. 基地

    public abstract class EmailTemplates
    {
        protected void BuildBody()
        {
            ReplaceVariables();
        }
        protected virtual string ReplaceVariables()
        {
            //code
        }
    }
    public abstract class CustomerEmailTemplates : EmailTemplates
    {
        protected override string ReplaceVariables()
        {
            //code
            base.ReplaceVariables();
        }
    }
    public class OrderEmailTemplates : CustomerEmailTemplates
    {
        protected override string ReplaceVariables()
        {
            //code
            base.ReplaceVariables();
        }
    }