views:

321

answers:

3

I created a class that's something like this:

    public class MovieTheaterList
    {
        public DateTime Date { get; private set; }
        public int NumTheaters { get; private set; }
        public Theater[] Theaters { get; private set; }
    }

    public class Theater
    {
        public string Name;
    }

I want to be able to add items to the Theaters array of the MovieTheaterList class, but when I try to access it, it is showing up as an IEnumerable type and there is no Add() method?

I'm used to using arrays in structs and classes in C/C++, but how can I add a new item to the array in .NET 3.5?

+4  A: 

Expose Theaters as an IList, not an array, and you'll be able to add / remove items from it. e.g.

public class MovieTheaterList
{
    // don't forget to initialize the list backing your property
    private List<Theater> _theaterList = new List<Theater>(); 

    public DateTime Date { get; private set; }
    public int NumTheaters { get; private set; }

    // set is unnecessary, since you'll just be adding to / removing from the list, rather than replacing it entirely
    public IList<Theater> Theaters { get { return _theaterList; } }
}
Jeremy Frey
@Jeremy, is there a reason why you are returning an "IList<>" instead of "List<>".
vobject
pZy -- http://stackoverflow.com/questions/400135/c-listt-or-ilistt/400144
Jeremy Frey
@Jeremy: You say that "you can add to an IEnumerable (via an extension method)". How? IEnumerable and IEnumerable<T> expose read-only sequences.
LukeH
Luke, you're right -- edited
Jeremy Frey
IEnumerable(<T>) is _not_ a readonly collection but the above mentioned add wouldn't work since ToList creates a new objected based on the IEnumerable it's called on. However if the IEnumerable returned by the property could be casted to IList or ICollection adding would change the sequence returned by the property. Not exposing a feature (such as Add) is not the same as making it impossible. I'm absolutely not recommending the cast operation mention just stating that IEnumerable has nothing to do with readability
Rune FS
@Rune FS: IEnumerable and IEnumerable<T> *are* read-only. It's possible that there might be an underlying mutable collection, and if that's the case then casting back to that type would allow you to modify it, but that doesn't change the fact that IEnumerable and IEnumerable<T> only represent a read-only sequence.
LukeH
Rune's right about converting ToList() and hitting .Add not adding to the underlying collection. Moral of the story: if you want a read-only collection, IEnumerable is a sound choice. If you want read-write, IList is the way to go.
Jeremy Frey
+1  A: 

Use

List<Theater> Theaters { get; private set; }

instead of an array of Theaters. You can initialize it using

Theaters = new List<Theater>();

In C# using lists is generally preferred over using arrays. You can easily convert between to an array using ToArray() but this way you don't have to worry about correctly sizing the array at creation time or, more importantly, resizing during execution.

AgileJon
You should use IList instead of List :)http://stackoverflow.com/questions/400135/c-listt-or-ilistt/400144
Rune FS
Not necessarily, it depends on who will be consuming this API. In general, exposing your API with interfaces will yield greater flexibility for you as the API writer. In my experience, the IList interface gives you very little additional flexibility but results in needless extra list copying.
AgileJon
+2  A: 

How about having the MovieTheatreClass extend a Generic List, for this functionality.

public class MovieTheatreList : List<Theatre>
{
    public DateTime Date { get; private set; }
}

public class Theatre
{
    public string Name;
}

This way, you get all the built in stuff of the List (like Count instead of having a separate NumOfTheatres property to maintain).

Scott Ferguson