简体   繁体   English

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

[英]How to modify method return value in all derived classes?

Imagine you have a class hierarchy as: 想象一下,您有一个类层次结构:

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";
    }
}

In most appropriate way, how can I write the code in a way that all "GetName" methods adds "XX" string to return value in derived class? 以最恰当的方式,我如何以所有“GetName”方法添加“XX”字符串以在派生类中返回值的方式编写代码?

For example: 例如:

         Derived1.GetName returns "Derived1XX"

         Derived2.GetName returns "Derived2XX"

Changing the code of GetName method implementation is not good idea, because there may exist several derived types of Base. 更改GetName方法实现的代码并不是一个好主意,因为可能存在几种派生类型的Base。

Leave GetName non-virtual, and put the "append XX" logic in that function. GetName保留为非虚拟,并将“追加XX”逻辑放在该函数中。 Extract the name (without "XX") to a protected virtual function, and override that in the child classes. 将名称(不带“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";
    }
}

This is a good use case for the decorator pattern. 这是装饰器模式的一个很好的用例。 Create a decorator that has a reference to a Base: 创建一个具有Base基础的装饰器:

class BaseDecorator : Base
{
    Base _baseType;

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

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

Construct a BaseDecorator with your chosen class (Base or Derived), and call GetName on that. 使用您选择的类(Base或Derived)构造BaseDecorator,并在其上调用GetName。

If you don't want to (or can't) modify original classes, you can use extension method: 如果您不想(或不能)修改原始类,可以使用扩展方法:

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

You'll be able to access new method as usual: 您将能够像往常一样访问新方法:

new Derived1().GetNameXX();

You could split the construction of the name into various overridable parts and then override each part in each of the different subclasses. 您可以将名称的构造拆分为各种可覆盖的部分,然后覆盖每个不同子类中的每个部分。 Below is one such example. 以下是一个这样的例子。

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";
  }
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM