views:

130

answers:

4

I have a simple lookup list that I will use to populate a dropdown in Silverlight. In this example I'm using US States.

I'm trying to figure out if its better to return a static list or use the yield keyword. Of the following two pieces of code, which is the preferred and why?

Version 1: Using yield return

public class States
{
    public static IEnumerable<string> GetNames()
    {
        yield return "Alabama"; 
        yield return "Alaska";
        yield return "Arizona";
        yield return "Arkansas";
        yield return "California";
        yield return "Others ...";
    }
}

Version 2: Return the list

public class States
{
    private static readonly IList<string> _names;

    static States()
    {
        _names = new List<string>() {"Alabama", 
                                     "Alaska",
                                     "Arizona",
                                     "Arkansas",
                                     "California",
                                     "Others ..." };

    }

    public static IList<string> GetNames()
    {
        return _names;
    }
}
+1  A: 

I think I'd prefer the list for this. The only advantage the yield method might offer over the List here is to avoid needing to keep all the elements in memory at once, but you're going to do that anyway.

Joel Coehoorn
Would the fact that the objects are only in memory during their use provide any benefit? Or would the load time out-weigh the memory cost?
bendewey
They *are* always in memory, since the code is loaded in memory...
Thomas Levesque
That's kinda my point.
Joel Coehoorn
A: 

Personally I'd prefer the List over the iterator, though I'd also look at embedding a resource containing such a list (perhaps XML, perhaps plain text) into your assembly and read that in your static constructor.

Jeffrey Hantin
+1  A: 

This may help explain why you should go with V1 http://startbigthinksmall.wordpress.com/2008/06/09/behind-the-scenes-of-the-c-yield-keyword/

Jonas
+1  A: 

The question you need to ask yourself is : "do I want the code that calls GetNames to be able to modify the list ?"

  • If the answer is yes, return a IList, implicitly saying : "read-write"
  • If the answer is no, return a IEnumerable, implicitly saying : "read-only"

Anyway, I think you should put the state names in a resource file, rather than hard-coding them (even though that list is unlikely to change in the short term...)

Here is what I would do :

public static IEnummerable<string> GetNames()
{
    foreach(string name in _names) yield return name;
}

This way you don't directly expose the list to the "outside world"

Thomas Levesque
Watch out with that least someone try: IList list = ((IList) SomeMethodThatReturnsEnumerable())
KeeperOfTheSoul
Yes, it's technically feasible... provided that it actually *is* an IList (which would not be the case for V1 code). Anyway, the return type indicates the intention, which is to provide a read-only list, but it doesn't prevent "illegal" operations.
Thomas Levesque
do you mean `yield return` in your sample?
bendewey
Yes, it's fixed now. Thanks !
Thomas Levesque