tags:

views:

249

answers:

3

Hello guys,

I need to design a simple piece of software, and i was wondering the best to do it.

First of all, sorry for the novice question: what is the best way to work with lists? i tried a few times and did not perceived the correct way to instanciate them and how to use them in OOP. Can anyone clear it up for me?

The second question is: i have the following classes (loosely formatted, not code)

Tenement:
tenementID Int32,
polygons Polygon, (here i need to use a list, but how?)
status TenementStatus;

Polygon:
polygonID Int32,
vertexes vertex (need to use a list here too),
areaPolygon;

Vertex:
vertexID Int32,
X Int32,
Y Int32;

Is my idea of these classes correct? Is there an easier way to do this?

A: 

Well in C# a List is simply a data structure representing a collection of objects that can be accessed by index. If that sentence makes sense, you understand pretty much all you need to know about lists (for this example at least). If not, you might start by taking a look at the MSDN documentation for the List(T) class.

Example:

// Declare a new list of vertices
List<Vertex> vertices = new List<Vertex>();

// Add a couple of vertices
vertices.Add(new Vertex(0, 0, 0));
vertices.Add(new Vertex(1, 100, 100));
vertices.Add(new Vertex(2, 50, 50));

// Get a vertex back out of the list by using its index
Vertex temp = vertices[1]; // this is the second vertex we added above
Donut
Thanks, you just answered my question.Could it be used like this?Polygon poly = new Polygon();poly.Vertices.Add(new Vertex(0,0,0));?
George
Yep, as long as the `Vertices` collection in the `Polygon` class is visible from the scope you're trying to access it from.
Donut
+3  A: 

In C#, you'll want to use the List<T> class to work with collections that are lists.

For example:

public class Tenement
{
     public Tenement()
     {
         this.Polygons = new List<Polygon>(); // Create the list here...
     }
     public int Id { get; set; }
     public IList<Polygon> Polygons { get; private set; }
     // ...

Edit: If you need to control how items are added or removed, such as checking to make sure the polygon is valid, you could also do:

public class Tenement
{
     public Tenement()
     {
         this.polygons = new List<Polygon>(); // Create the list here...
     }
     private List<Polygon> polygons;

     public int Id { get; set; }
     public IEnumerable<Polygon> Polygons { 
        get { return this.polygons; }
     }
     public void AddPolygon(Polygon polygon) {
         // Do extra stuff here, then:
         this.polygons.Add(polygon);
     }
     // ...
Reed Copsey
Hello Reed,Why do i have to use a specific private set? Can't i use a normal set?Also, i must instantiate when creating Tenement a new list<polygons>? i understand your code, just checking the "why".
George
Also, do i need methods inside my class to add/remove elements to a certain list? example: Tenement.AddPolygon(polygonObject)?Whats the easy way? Sounds pretty simple to create a Add/Remove.
George
@George: It's a bad idea to make set public in this case, because we don't want somebody, outside our class, to "Set" our polygons. THey can still do: myTenement.Polygons.Add(new Polygon()); --- this is because they're adding to your EXISTING list, not creating a new one. There's no reason to make "AddPolygon()" methods, since they can just add it to your list.
Reed Copsey
@George: That being said, sometimes you want to control HOW things are added to a list. I'll edit my answer to include details.
Reed Copsey
@George: the way Reed did this is the standard recommended pattern to deal with collection members in .NET (for other languages/frameworks, it may well be different). In particular: collection properties should generally not be settable; consequently, they should be initialized by the class itself (probably in constructor); and class shouldn't have methods like `AddPolygon()` - the client is instead supposed to do `Polygons.Add(...)`. This is all covered by Framework Design Guidelines: see http://msdn.microsoft.com/en-us/library/ms229042.aspx
Pavel Minaev
Also, this book covers this and other similar questions in even more detail: http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613 (it's written by Microsoft people who are responsible for style guidelines for .NET class libraries in Microsoft itself)
Pavel Minaev
Riffing a bit more on Reed's second option, note that .Net provides a wrapper type for list properties that are not open for mutation by clients: public System.Collections.ObjectModel.ReadOnlyCollection<Polygon> Polygons { get { return new ReadOnlyCollection<Polygon>(this.polygons); }This provides richer semantics than the bare IEnumerable, and prevents the client from casting back to List<Polygon> to bypass the protection.
Abraham Pinzur
@Abraham, a good point, except for one nit where creating a new wrapper on every call to `get` is a bad idea. Among other things, user is entitled to expect that `x.Polygons == x.Polygons` is `true`. Creating a single wrapper in constructor, and returning it from `get`, accomplishes this.
Pavel Minaev
A: 

If you're looking for a simple List object...

List<Vertex> vertices = new List<Vertex>();

and

List<TenementStatus> statuses = new List<TenementStatus>();

That's the simple declaration for your needs...

Justin Niessner