C# que trata con tipos derivados, refactorización

I am using a third-part .NET library that has the following classes.

Shape (the abstract base class)

(all the below classes derived from him)

rectángulo

Círculo

Triángulo

all of these classes has a property called Area

I am going through an array of Shape(s), and set the area

P.S: Area is not a property of the Shape, instead it is a property of each class.

entonces mi código se ve así:

if (shapeVar is Reactangle)
{
   (shapeVar as Rectangle).area = value;
}

if (shapeVar is Circle)
{
   (shapeVar as Circle).area = value;
}

if (shapeVar is Triangle)
{
   (shapeVar as Triangle).area = value;
}

Is there a better way to do this? I feel like it is stupid, but I didn't find other way to do it

Estoy usando .NET 4

preguntado el 03 de mayo de 12 a las 18:05

3 Respuestas

You can use reflection to access the area property of each shape, although there is a small performance cost:

shapeVar.GetType().GetProperty("area").SetValue(shapeVar, value, null);

contestado el 03 de mayo de 12 a las 18:05

Thanks for the answer. I ended up keeping the code as it is. I didn't want to use reflection - Ghassan Karwchan

you can wrap Rectangle, Circle and Triangle classes (that come from the third party assembly) and create 3 new classes in your own code.

Then you can have an interface for e.g:

        public interface IShape
        {
            double Area{get;set;}
        }

Make the wrapped classes to implement this common interface.

After that you can use all three of these classes in your code in a common way without having to know what their actual concrete classes are. (by referring to Interface type rather than Shape base type)

Respondido el 27 de junio de 12 a las 09:06

Why not have the Area be a method that returns from the derived type instead of being set?

public abstract class Shape
{
    abstract public double Area();
}

public class Square : Shape
{
    double sideLength;
    public double Area
    {
        return sideLength * sideLength;
    }
}

public class Circle : Shape
{
    double radius;
    public double Area
    {
        return Pi * r * r;
    }
}

If you want to stick to setting the area, you could move your Area into the base class :

public abstract class Shape
{
    public double Area;
}

public class Square : Shape
{
    ...
}

and you look through shapes setting the area based on the derived type you could do :

foreach (Shape shape in shapes)
    switch(typeof(shape))
    {
        case typeof(Square))
        {
            shape.Area = value; //I imagine this is derived type specific
            ...
        }
    }

contestado el 03 de mayo de 12 a las 19:05

the author already mentioned that all those classes are coming from a 3rd party library. - user694833

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.