简体   繁体   中英

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?

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.

Leave GetName non-virtual, and put the "append XX" logic in that function. Extract the name (without "XX") to a protected virtual function, and override that in the child classes.

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:

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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