0
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

Eren
  • 632
  • 1
  • 8
  • 16
  • "Write properties of Recatangle class object..." I'm unsure I follow. – Mister Epic Jan 25 '14 at 13:30
  • 1
    No, it is impossible, because the base class nothing knows about derived class. – Hamlet Hakobyan Jan 25 '14 at 13:32
  • Frankly it's more work to do it any other way. – T McKeown Jan 25 '14 at 13:36
  • The only other way to do this and keep all the code in base is to reflect over the properties at runtime in the .ToString() but that doesn't seem like a good idea for this. – T McKeown Jan 25 '14 at 13:38
  • 1
    I now see you also tagged this question `reflection`. Is your actual question ["How to get the list of properties of a class?"](http://stackoverflow.com/questions/737151/how-to-get-the-list-of-properties-of-a-class)? – CodeCaster Jan 25 '14 at 13:40
  • Using reflection for such a task is really bad design. Reflection is slow and this really should be done with OOP patterns, namely polymorphism. – Ondrej Janacek Feb 14 '14 at 10:10
  • Have you not found any of the provided answers helpful? What's the problem? – Ondrej Janacek Mar 03 '14 at 12:38
  • I have to override ToString method in each class. It causes the code duplication. It is not a problem but code duplication is not good for code qualty – Eren Mar 04 '14 at 06:38

2 Answers2

2

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();
    }
}
Ondrej Janacek
  • 12,486
  • 14
  • 59
  • 93
0

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.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • How's that different from having to update the base class every time you create a new derived type? – dcastro Jan 25 '14 at 13:37
  • You still have to update it, but it is in a separate class. Like I said, you don't want to know in your base class what types implement your base class. – CodeCaster Jan 25 '14 at 13:38
  • 1
    You don't want your base class to be aware of derived classes *because* you will then have to update it. For that same reason, you wouldn't want *any* class to be aware of a type's derived types. All of this is explained by the LSP - the ShapePrinter is not guaranteed to work for *all* types derived from `Shape`. Unfortunately, this is an Occam's razor situation: the right approach is the simplest approach - have every derived type override ToString. – dcastro Jan 25 '14 at 13:44
  • _"because you will then have to update it"_ - that's not the only reason you wouldn't want that. I entirely agree with your reasoning (and I hope that is clear from my answer now), I'm just giving OP some pointers if he's absolutely sure he wants to solve it this way and ignore the mechanisms that were meant for this, like `override`. – CodeCaster Jan 25 '14 at 13:47
  • This is also not applicable at all if any of the derived classes are not under you control, you may not even be aware they exist. – Vadim Jan 25 '14 at 14:12