简体   繁体   中英

Get child class properties from base class

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

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

Suppose that I created an object from Rectangle class. Are there any way to write properties of Rectangle class object with values via created object without overriding toString() method?


Edit:

Actually my purpose was creating a generic ToString() method for all child classes.

I modify my code

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

Result:

width : 0
height : 0

But now, I have to override ToString() method for all child classes. I could not find solution for this code duplication

If you just need to preserve the toString method you can do it like

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();
    }
}

You don't want to access derived classes in the base class, because then you must update your base class for every derivation you create.

If you're absolutely sure you don't want to just override ToString() (and it would be nice of you to explain why not, because that approach makes the most sense in this scenario), you can do something like this:

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

But then you're practically building a poor man's implementation of virtual methods that you still have to maintain for every type you add. This is exactly the same you can accomplish using override ToString() , so you must have compelling reasons not to use that.

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