如何在所有派生类中修改方法返回值?

时间:2014-09-30 20:58:54

标签: c# .net oop design-patterns

想象一下,您有一个类层次结构:

class Base
{
    public virtual string GetName()
    {
        return "BaseName";
    }
}

class Derived1 : Base
{
    public override string GetName()
    {
        return "Derived1";
    }
}

class Derived2 : Base
{
    public override string GetName()
    {
        return "Derived2";
    }
}

以最恰当的方式,我如何以所有" GetName"的方式编写代码?方法增加" XX"字符串在派生类中返回值?

例如:

         Derived1.GetName returns "Derived1XX"

         Derived2.GetName returns "Derived2XX"

更改GetName方法实现的代码并不是一个好主意,因为可能存在多种派生类型的Base。

5 个答案:

答案 0 :(得分:7)

GetName保留为非虚拟,并将“追加XX”逻辑放在该函数中。将名称(不带“XX”)提取到受保护的虚拟函数,并覆盖子类中的名称。

class Base
{
    public string GetName()
    {
        return GetNameInternal() + "XX";
    }

    protected virtual string GetNameInternal() 
    {
        return "BaseName";
    }
}

class Derived1 : Base
{
    protected override string GetNameInternal()
    {
        return "Derived1";
    }
}

class Derived2 : Base
{
    protected override string GetNameInternal()
    {
        return "Derived2";
    }
}

答案 1 :(得分:3)

这是装饰器模式的一个很好的用例。创建一个引用Base的装饰器:

class BaseDecorator : Base
{
    Base _baseType;

    public BaseDecorator(Base baseType)
    {
        _baseType = baseType;
    {

    public override string GetName()
    {
        return _baseType.GetName() + "XX";
    }
}

使用您选择的类(Base或Derived)构造BaseDecorator,并在其上调用GetName。

答案 2 :(得分:2)

如果您不想(或不能)修改原始课程,可以使用扩展方法:

static class Exts {
    public static string GetNameXX (this Base @this) {
        return @this.GetName() + "XX";
    }
}

您可以像往常一样访问新方法:

new Derived1().GetNameXX();

答案 3 :(得分:1)

您可以将名称的构造拆分为各种可覆盖的部分,然后覆盖每个不同子类中的每个部分。 以下是一个这样的例子。

public class Base {
  public string GetName() {
    return GetPrefix() + GetSuffix();
  }
  protected virtual string GetPrefix() {
    return "Base";
  }
  protected virtual string GetSuffix() {
    return "";
  }
}

public class DerivedConstantSuffix : Base {
  protected override string GetSuffix() {
    return "XX";
  }
}

public class Derived1 : DerivedConstantSuffix {
  protected override string GetPrefix() {
    return "Derived1";
  }
}

public class Derived2 : DerivedConstantSuffix {
  protected override string GetPrefix() {
    return "Derived2";
  }
}

答案 4 :(得分:0)

覆盖可以调用它的基本功能......然后你可以修改基类来附加你想要的字符。