Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anonymous type collections?

I am looking for best practices for creating collections made from anonymous types.

There are several approaches - this one and most answers on this thread assume that the whole anonymous collection can be constructed in one statement.

As anonymous types are usually used to replace classes that are to be used to store temporary (as put forward in this SO answer), I would like to avoid creating and using a class for anonymous collections, as this post suggests.

In my case, I am iterating over a collection - for each item in the collection I would like to collect related objects in an anonymous type (acting as a tuple). I need these anonymous types to be put in a collection and then sort them for further work.

Other approaches I have considered:

  1. Use an object[] or ArrayList (losing the benefit of the anonymous type)
  2. Creating a wrapper class for the required items (removing the need for the anonymous type)

This is the only place in my code that I need such a collection - what would be the best approach?

Additional Information:

I am working with legacy .Net 1.1 objects, so the collections I am working with are strongly typed collections implementing IEnumerable, and as such most Linq extension methods such as .Select won't work:

Code sample

foreach (Item item in myItems)
{
    foreach (Confirmation confirmation in item.GetConfirmations(true))
    {
        if (lastParentId != item.ParentId)
        {
            lastParentId = item.ParentId;
            parentObject = new ParentItem(lastParentId);
        }

        itemHolder = new ArrayList { item, confirmation };
        if (parentObject!= null)
        {
            itemHolder.Add(parentObject.Rate);
        }

        sortConfirmations.Add(confirmation.Date, itemHolder);
    }
}

// Use sortConfirmations

Resolution

I ended up using a generic dictionary to collect the related items together and using .OrderBy() to sort them - ugly, but it works... and is better than the existing code.

like image 321
Oded Avatar asked Mar 19 '09 10:03

Oded


2 Answers

If you're happy with an array, you can use an array initializer:

var items = new[] {
    new { Foo = "def" },
    new { Foo = "ghi" },
    new { Foo = "jkl" }
};

You can then call ToList() if you want to get a List<T> out. Marc's solution will be slightly more efficient than calling ToList() due to not needing the extra copying, but I think I'd probably use the "array and then ToList()" solution in most cases as there's less clutter. Of course, if performance is crucial for that bit of code, it changes things.

EDIT: As you're iterating over a collection, just use Select:

var anonymousItems = items.Select (item => new { Foo=item.Foo, 
                                                 Bar=item.Other })
                          .ToList();
like image 193
Jon Skeet Avatar answered Sep 27 '22 22:09

Jon Skeet


For a very different answer... LINQ?

In my case, I am iterating over a collection - for each item in the collection I would like to collect related objects in an anonymous type (acting as a tuple). I need these anonymous types to be put in a collection and then sort them for further work.

That sounds like:

var list = (from item in collection
          from related in item.Relationship
          order by ...something...
          select new {item,related}).ToList()
like image 28
Marc Gravell Avatar answered Sep 27 '22 21:09

Marc Gravell