2013-07-27 29 views
0

请看下面(伪)模式:基类中的递归抽象ToString()?

public abstract class Animal { 

    public abstract AnimalType { get; } 

    public abstract override string ToString() { 
      return String.Format("{0}={1}", AnimalType, this.ToString()); 
                 ^
               // does this even work? 
    } 

} 

这将迫使每一个从它派生类是这样的:

public sealed class Horse : Animal { 

    // horse specific declaration 
    private string _name; 
    private int _age; 

    // forced 
    public override AnimalType { 
      get { return AnimalType.Horse; } 
    } 

    // horse specific declaration 
    public Name { 
      get { return _name; } 

    public Horse(string name, string age) { 
      _name = name; 
      _age = age; 
    } 

    // forced 
    public override string ToString() { 
      return String.Format("{0}({1}", _name, _age); 
    } 

}

这将产生以下的输出:

Horse =MyHorseName(3); 
Tiger =SomeOtherAttributesBecauseTigerIsDifferent 

问题是:当我想f orce ToString()在派生类中,我不能在基类中有任何功能。我希望派生类提供它自己的字符串表示,但仍然希望有一个字符串表示,告诉我在这种情况下,它是什么类型的动物。

+1

正是你想要达到什么目的? –

+1

'公共抽象重写字符串ToString()'????????????? OMG,这超过了我的期望:-) –

+0

你也许可以解释为什么要强制压倒一切,并提供(重写)的基本功能? (从我的理解 - 您的解决方案可能是你想要的东西已经在基本/一般格式及部分在子类中有部分数据) –

回答

5

我认为最好的方法是声明并呼吁独立protected abstract string GetAttributes()方法。此外,你可以使用sealed防止子类覆盖ToString()实现:

public abstract class Animal { 
    public abstract AnimalType { get; } 

    public sealed override string ToString() { 
      return String.Format("{0}={1}", AnimalType, this.GetAttributes()); 
    } 

    protected abstract string GetAttributes(); 
} 

public sealed class Horse { 
    protected override string GetAttributes() { 
     return String.Format("{0}({1}", _name, _age); 
    } 
} 

如果Horse试图在这一点上覆盖ToString,这样会得到一个编译错误。同时,它被迫执行GetAttributes

+0

谢谢,我会坚持你的建议,虽然可能会令人困惑的是,派生类的“ToString()”方法只给出了基类的字符串表示,而“GetAttributes()”则用于此目的。 :) – Atrotygma

+0

+1用于“密封”方法.. –

0

我不知道,也许推入的ToString代码了一些默认值的基类中使用的变量,但有子类进行更改。因此,基类中的ToString()代码不需要被覆盖,但会提供自定义的输出,因为基类变量会随着孩子想要的变化而变化。例如考虑:

abstract class cbase 
    { 
    internal string _var1 = "def1", _var2 = "def2"; 

    public override string ToString() 
    { 
     return string.Format("{0} - {1}", _var1, _var2); 

    } 
    } 
    class cchild1 : cbase 
    { 

    public cchild1() 
    { 
     _var1 = "umm"; 
     _var2 = "ok"; 

    } 
    } 
    class cchild2 : cbase 
    { 

    } 

因此,对于上面的代码:

new cchild1().ToString() 

将输出

umm - OK 

new cchild2().ToString() 

将输出:

def1 - def2 

所以用这种方式,您不必在每个子类中重写ToString,但输出格式仍然与您在基类中定义的所有继承类保持一致。但是如果需要的话,你也可以自由地重写ToString。