1

i am sorry if this has been asked before, but i don't really know if i'm phrasing the question right:

So, let's say i have this classes:

class Shape{
int Area
}

class Triangle:Shape{
string type_of_triangle;
}

class Star:Shape{
int Number_of_Points;
}

and a function that returns a shape typed List wich contains both triangle and shape objects in it. when i try to access triangle's or star's properties, visual studio only let's me access the parent's properties.

So, basically my question is: How can i access the child's properties if the objects are stored in a parent-type variable??

  • 1
    By using a list of the base class or a lesser derived type, you're effectively asserting that you do not care about more derived types' additional members. If you in fact *do* care, then maybe that's a sign you have the wrong design, either in the class hierarchy or in the method working with the list. – Anthony Pegram Apr 22 '11 at 04:35
  • well, i puted all of the objects in a parent list because they were the outputs of a method, can i do anything else to avoid that? – Joaquin Grunert Apr 22 '11 at 05:09
  • Depends what you're doing. If you post more of your code, or the general idea of what you're *really* doing, you might get better advice. Generally speaking, you'd like to avoid resorting to long blocks of type checking if you can. – Anthony Pegram Apr 22 '11 at 05:18

2 Answers2

3
Shape unknownShape = new Triangle();

if(unknownShape is Triangle){
    ((Triangle)unknownShape).type_of_triangle;
}
Ortiga
  • 8,455
  • 5
  • 42
  • 71
  • 2
    Use operators `as` and `!= null`, rather then `is` and `cast` – abatishchev Apr 22 '11 at 14:48
  • 1
    @abatishchev: Afraid that your program might run 10 ms slower? – Timwi Apr 22 '11 at 14:49
  • @Timwi: That's about operators purpose understanding. Also see [FxCop rule](http://msdn.microsoft.com/en-us/library/ms182271%28VS.80%29.aspx) – abatishchev Apr 22 '11 at 14:54
  • @abatishchev: I see — you’re seeing purpose where there is none, backed up by an appeal to authority. – Timwi Apr 22 '11 at 15:40
  • @Timwi: Is [Jon Skeet's opinion](http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr/496167#496167) is enough for you? Huh? – abatishchev Apr 22 '11 at 15:57
  • @Timwi: [the cost of is/as/casting in terms of IL:](http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/01/30/is-as-and-casting.aspx) – abatishchev Apr 22 '11 at 16:05
  • @abatishchev: Even more appeals to authority? No, nobody’s mere opinion is any good — only *reasoning* is. Jon Skeet’s answer only lists mantras, no reasoning. The second link you gave has faulty reasoning and a non-sequitur conclusion. – Timwi Apr 22 '11 at 17:38
-1

I would suggest giving a little more thought to the design of you class hierarchy. Off the top of my head I would propose you can place all of the properties you have defined for your derived shapes within the parent. Further, you might want to consider making some of them methods which return values.

While it is not part of your current example, any shape, including a circle has a finite number of points (a circle simply has zero). A generic "shape_family" property might represent the string classification for the specific derivation of the shape class ("Triangle", "Star", etc).

The shape_subtype might represent specific variations ("Right Triangle", "Isoceles Triangle", etc.). Then, if you define the points as, well, POINTS and add them to a list, you will not only have specified locations for them (if that is not beyond the scope of your program), but you will have a count as well. From there you can probably work out some additional logic to map the sides/verticals, and compute such things as Area, perimeter, etc.

Consider (but please note that I am only now branching into C# and Java from vb.net, so if I butcher the code here, try to focus on the class structure, NOT my syntax . . .):

Edit: 4/22/2011 7:41 AM - Ooops. Forgot to make the Class abstract. If methods on a class are defined as "abstract", then the class itself must be abstract as well, meaning the abstract base cannot be directly instantiated. Here is a link to more info on abstract classes and methods/

public abstract class Shape
{ 
    int Area; 
    string shape_family;
    string shape_subtype;
    list<point> Points

    public int number_of_points()    
    {
        return points.count
    }        
    public abstract int perimeter_lenngth()
    public abstract int area()
}  

class Triangle : Shape { 

    //Example of Triangle-specific implementation:
    public override int perimiter_length {
       //You code to obtain and compute the lengths of the sides
    }

    //Example of Triangle-specific implementation:
    public override int area {
        //Your code to obtain and compute        
    }
}

class Star : Shape{

    //Example of Star-specific implementation:
    public override int perimiter_length {
       //Your code to obtain and compute the lengths of the sides
    }

    //Example of Star-specific implementation:
    public override int area {
        //Your code to obtain and compute        
    }
}

class Circle : Shape {
    point center;
    int radius

    // Example of Circle-specific implementation:
    public override int perimiter_length {
        return 2*3.14*radius
    }

    // Example of Circle-specific implementation:
    public override int area {
        return 3.14*radius^2
    }
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
XIVSolutions
  • 4,442
  • 19
  • 24
  • Oh, yeah. And then, if you need to determine the specific derived type as you pull objects from the list, you can employ the method illustrated by Andre above. But some variant of what I described SHOULD deliver what you seem to be asking - access to the properties of the derived classes, without having to go through the type-checking process. THis will also be more flexible if you find that you need to modify your implementation (such as my suggested functions for area and perimiter, as opposed to the values you were storing for area (which can be computed). – XIVSolutions Apr 22 '11 at 06:18
  • In any class hierearchy, do your best to define the properties and methods such that as many as posible can be generalized. Case in point here would be the "number_of_points" property. As mentioned above, it might seem that this property might not apply to a circle, but in fact it does - a circle has zero points. – XIVSolutions Apr 22 '11 at 14:46
  • @Whoever Cast the downvote: if youare going to downvote my answer, could you let me know the reasoning? I am here as much to learn as anyone else. – XIVSolutions Apr 22 '11 at 22:20