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 th
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?
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.
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);
You can create collection like this
private IList<(string Name, bool listenToQueue)> _listeners;
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.
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()