views:

3368

answers:

7

In C# 3.0 you can create anonymous class with the following syntax


var o = new { Id = 1, Name = "Foo" };

Is there a way to add these anonymous class to a generic list?

Example:

var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };

List<var> list = new List<var>();
list.Add(o);
list.Add(o1);

Another Example:

List<var> list = new List<var>();

while (....)
{
    ....
    list.Add(new {Id = x, Name = y});
    ....
}
+3  A: 

Yes, you can say List<object> and things will work. However, list[0].Id won't work. This will work in C# 4.0 by having a List<dynamic>.

UPDATE: As mentioned in the comments, this List<dynamic> trick won't get you IntelliSense, but it will work at runtime.

Jeff Moser
It's not strongly-typed, though, in the sense that you'll have no compiler intellisense support for the items in the list.
Joel Coehoorn
This is the kind of things I fear people will do with dynamic.
erikkallen
I didn't say it was a *great* idea, but that it was possible :-) There could be a need if storing objects from Ruby for example.
Jeff Moser
But in those cases the source type is dynamic after all, it makes no sense to use a List<dynamic> for anonymous types.
Dykam
+1  A: 

Check out this example for creating/using Lists with anonymous classes.

Jess
Post a quick example and I'll upvote.
Joel Coehoorn
+17  A: 

You could do:

var list = new[] { o, o1 }.ToList();

There are lots of ways of skinning this cat, but basically they'll all use type inference somewhere - which means you've got to be calling a generic method (possibly as an extension method). Another example might be:

public static List<T> CreateList<T>(params T[] elements)
{
     return new List<T>(elements);
}

var list = CreateList(o, o1);

You get the idea :)

Jon Skeet
The correct syntax (at least in 3.5) is var list = new[] {o, o1};
DHornpout
@DHornpout: That would give an array, not a List<T>.
Jon Skeet
What version are you using? This is the compiler error I gotError 1 'System.Array' does not contain a definition for 'ToList' and no extension method 'ToList' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?)
DHornpout
@DHornpout: Do you have "using System.Linq;" at the top of your file? ToList is a LINQ operator.
Jon Skeet
(You also need a reference to System.Core of course.)
Jon Skeet
Got it.. Need to include "using System.Linq". Thanks.
DHornpout
+2  A: 

I guess

List<T> CreateEmptyGenericList(T example) {
    return new List<T>();
}

void something() {
    var o = new { Id = 1, Name = "foo" };
    var emptyListOfAnonymousType = CreateEmptyGenericList(o);
}

will work.

erikkallen
Yes this solution will help solve initialize the Anonymous array. Thanks.
DHornpout
A: 

You can do it this way:

var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };

var array = new[] { o, o1 };
var list = array.ToList();

list.Add(new { Id = 3, Name = "Yeah" });

It seems a little "hacky" to me, but it works - if you really need to have a list and can't just use the anonymous array.

Jermismo
A: 

This issue would of course be solved by allowing the language to define an anonymous class as implementing an interface - java style. This is something I find lacking on an almost daily basis.. Drunken monkeys came up with the crap we know as C# anonymous classes. Why is MS implementing new features when the old features are so half assed?

Not wanting to start a C# vs. Java holy war here, but gosh how wrong you are. Anonymous classes in C# and anonymous classes in Java have close to nothing in common. The only realistic use-case for Java's anonymous classes that implement an interface is for event listeners, which in C# you can do with a lambda expression. C#'s anonymous classes provide a solution for a completely different use-case; one which Java does not appear to address in any way.
Timwi
A: 

It is too late to in this thread, but useful for viewers who want this in future. here is the answer. thanks, Dutt

        string result = String.Empty;

        var list = new[] { 
                            new { Number = 10, Name = "Smith" },
                            new { Number = 10, Name = "John" } 
                         }.ToList();
        foreach (var item in list)
        {
            result += String.Format("Name={0}, Number={1}\n", item.Name, item.Number);
        }

        MessageBox.Show(result);
Dutt
Dutt, your code should work without the .ToList() at the end.
DHornpout