【问题标题】:Can I call a derived method from base class?我可以从基类调用派生方法吗?
【发布时间】: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


【解决方案1】:
  1. Virtual methods
  2. Override
  3. Base

    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();
        }
    }
    

【讨论】:

  • 那行得通。所以我基本上只是在方法签名中使用了错误的关键字。非常感谢。
猜你喜欢
  • 2013-10-08
  • 2017-08-02
  • 2014-03-17
  • 2021-03-08
  • 2011-05-11
  • 2016-07-06
  • 2014-02-15
  • 2013-03-28
  • 2013-04-11
相关资源
最近更新 更多