从基类获取子类属性

时间:2014-01-25 13:29:05

标签: c# oop reflection

public abstract class Shape
{
    public String toString()
    {
        // ...
        return "";
    }
}

public class Rectangle : Shape
{
    public Double width { get; set; }
    public Double height { get; set; }
}

假设我从Rectangle类创建了一个对象。有没有办法通过创建的对象写入Rectangle类对象的属性而不重写toString()方法?


编辑:

实际上我的目的是为所有子类创建一个通用的ToString()方法。

我修改了我的代码

public abstract class Shape
{
    public virtual String ToString(Shape shape)
    {
        String result = String.Empty;

        foreach (var property in shape.GetType().GetProperties())
        {
            result += property.Name + " : " + property.GetValue(shape, null) + "\n";
        }

        return result;
    }
}



  public class Rectangle : Shape, IRectangle
    {
        public Double width { get; set; }
        public Double height { get; set; }

        public override String ToString()
        {
            return base.ToString(this);
        }
    }

结果:

width : 0
height : 0

但是现在,我必须为所有子类重写ToString()方法。我找不到这个代码重复的解决方案

2 个答案:

答案 0 :(得分:2)

如果您只需要保留toString方法,就可以像

那样保留
public abstract class Shape
{
    public String toString()
    {
        return InternalToString();
    }

    protected abstract string InternalToString();
}

public class Rectangle : Shape
{
    public Double width { get; set; }
    public Double height { get; set; }

    protected override string InternalToString()
    {
        return width.ToString() + ", " + height.ToString();
    }
}

答案 1 :(得分:0)

您不希望访问基类中的派生类,因为您必须为您创建的每个派生更新基类。

如果你完全确定你不想只是覆盖ToString()(你会很高兴解释为什么不这样做,因为这种方法在这种情况下最有意义),你可以做像这样的东西:

public abstract class Shape
{
    public String toString()
    {
        return ShapePrinter.GetString(this);
    }
}

public static class ShapePrinter
{
    public static string GetString(Shape shape)
    {
        if (shape is Rectangle)
        {
            return GetRectangleString(shape as Rectangle);
        }       
        if (shape is Circle)
        {
            return GetCircleString(shape as Circle);
        }

        throw new ArgumentException("shape");

    }

    private static string GetRectangleString(Rectangle rectangle)
    {
        return string.Format("Rectangle: {0} x {1}",
                              rectangle.Width, rectangle.Height);
    }

    private static string GetCircleString(Circle circle)
    {
        return string.Format("Circle: radius {0}", circle.Radius);
    }
}

但是,实际上你正在建立一个穷人的虚拟方法实现,你仍然必须为你添加的每种类型维护。这与使用override ToString()完成的操作完全相同,因此您必须有令人信服的理由不使用它。