Question

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.

Was it helpful?

Solution

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()

OTHER TIPS

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();

One option is to use an example item to create the collection via generic type inference, for example:

    static List<T> CreateEmptyList<T>(T template) {
        return new List<T>();
    }
    void Foo() {
        var list = CreateEmptyList(new { Foo = "abc" });
        list.Add(new { Foo = "def" });
        //...
    }

You can also do this without creating an instance (but using an anonymous method that never gets caller), but I don't think it saves anything really... we might not create an instance of the object, but we do create an instance of a delegate, so not much of a saving...

You also mention sorting the data; see the reply here for a way to use List<T>.Sort with a lambda, and hence with anonymous types - i.e.

list.Sort(x=>x.Foo);

LINQ is the way to go. Assuming you want to fetch the related objects A, B and C of every item in a collection items and sort by the related object A you would go as follows.

var relatedObjects = items.
       Select(item => new { A = item.A, B = item.B, C = item.C } ).
       OrderBy(item => item.A);

You get a collection of items of an anonymous type with the three properties A, B and C set to the related objects ordered by the related object A.

I did not verify that, but you should be able to extend the relatedObject collection later. Just do the following to add a single new item. This should work because there is only one anonymous type per assembly I think if the names and types of each property match.

relatedObjects = relatedObjects.Union(
   Enumerable.Repeat(new { A = someA, B = someB, C = someC }, 1))

Quite ugly because of the Enumerable.Repeat() but becomes quite nice if you union with a collection of new items instead of a single new item.

I stumbled upon this question while looking for a way to create a temporary list of temporary objects. Why would I want to create such a thing? I was looking for a quick way to return JSON for a list of objects made from some values of another object. Here's what I mean.

Suppose I have an Employee class on the server side which looks like the following in C#:

public class Employee
{
          public int Id;
       public int businessGroupId;
       public string title;
       public int positionId;

       public string firstName;
       public string lastName;
       ...
}

Furthermore I have a collection of those objects which I can easily iterate through, something like the following:

List<Employee> allEmployees  = new List<Employee>();

Now, I want to return to my calling web page the entire collection of Employees, but I only want the firstName, lastName for each. I want them returned as JSON.

Here's The Important Point

I do not want to return every property in the Employee Object.

I know I can easily create an anonymous type by iterating through the allEmployees collection and building a new object each time.

It would look something like the following:

foreach (Employee e in allEmployees)
{
    var tempObj = new {F_Name=e.firstName, L_Name=e.lastName};
}

What's The Type Of An Anonymous Type? :)

The trick now is that I want an entire collection (List<>)of these anonymous objects. However, I have no way to provide the List a type that I will be using. I cannot create a List<unknown> allTempObjects = new List<unknown>();

Or can I?

With dynamic, It Is Possible

I can do the following and it works great:

List<dynamic> allEmployees  = new List<dynamic>();

foreach (Employee e in allEmployees)
{
           var tempObj = new {F_Name=e.firstName, L_Name=e.lastName};
        allEmployees.Add(tempObj);
}

// use the JavaScript Serializer to serialize the dynamic collection
JavaScriptSerializer jss = new JavaScriptSerializer();
// write the result out to the HTTP Stream (HtmlTextWriter in overridden Render method)

 writer.Write(jss.Serialize(allEmployees));

You will see JSON on the client side which looks like the following:

[
    {
      F_Name: "Seth",
      L_Name: "Godin"
    },
    {
       F_Name: "Charles",
       L_Name: "Petzold"
    },
    {
       F_Name: "Jeff",
       L_Name: "Prosise"
    }
]

Finally, you may question why I want to do this. The simple answer is that I want to new type which is only used to serialize to send to my client. A great reason for an anonymous type and an anonymous collection of anonymous types, don't you think?

this one and most answers on this thread assume that the whole anonymous collection can be constructed in one statement.

Yes, you normally create a collection of anonymous type in a single statement. If you need more statements, you may end up with a pretty useless collection of different anonymous types.

Anonymous types are useful when you create them in a single statement, and use them right away. If the creation of the collection or the further processing is a bit more complex, the anonymous type loses some of it's usefulness. For example, you can't efficiently pass an anonymous type along to a method for processing, as the method doesn't know the type of the object and thus have to use reflection to get anything out of it.

If you are going to repeatedly look for items in this collection of anonymous types, you may want to create a named type so that you can put them in a Dictionary for much faster lookup.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top