Cast List<object> to AnonymousTypes list

asp.net, c#

Solution

You can take advantage of generics and type inference to create the list for you:

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

Usage like:

var someList = CreateAnonymousList(new { foo = 1 }, new { foo = 2 }, new { foo = 1 });

someList.Where(x => x.foo == 1);

Naturally you won't be able to do much with it. You'll never be able to strongly type it in your code to anything other than `var` or return it out from your method or anything you normally wouldn't be able to do with anonymous types. If you want to do more, you'll just have to bite the (small) bullet and define a class for your anonymous type.

Rereading your question, you can still perform LINQ queries on an array:

var someArray = new[]{new { foo = 1 }, new { foo = 2 }, new { foo = 1 }};
someArray.Where(x => x.foo == 1)

So unless you are modifying it (say via standard `List<T>` operations like `Add` or `Remove`) then there's no reason to have to convert it to a `List<T>`.

I realize that maybe you want to still be able to pass it back (for some reason) and still do operations on it without knowing its anonymous type. In that case you could treat it as `dynamic` and perform the operations at runtime, but you lose any intellisense/strong typing that you'd normally have with the anonymous type:

List<dynamic> someDynamicList = new List<dynamic>() {new { foo = 1 }, new { foo = 2 }, new { foo = 1 }};
someDynamicList.Where(x => x.foo == 1)

One last method as pointed out by Tim Schmelter leveraging Jon Skeet's CastByExample, but extended to convert your collection with an extension method:

public static IEnumerable<T> CastByExample<T>(this IEnumerable source, T example)
{
    foreach(object entry in source)
        yield return (T)entry;
}

public static IEnumerable CreateAnonymousData()
{
    return new[]{new { foo = 1 }, new { foo = 2 }, new { foo = 1 }};
}

With usage like:

var anonymousData = CreateAnonymousData();
var typedAnonymousData = anonymousData.CastByExample(new { foo = 1 });
typedAnonymousData.Where(x => x.foo == 1);

This takes advantage of the fact that within the same assembly, anonymous types declared with the same parameter names, types, and order compile to the same type. This won't work if you need to call your `CreateAnonymousData` from outside the current assembly and you have to maintain the signature of your `foo` anonymous type everywhere you use it (add/change its signature, you must update it everywhere you use it or you're going to have a bad time).

But I think it's becoming more clear now that the best solution to this is to simply define a class representation of your anonymous type.

Problem

I have populated the follow list with objects of type `AnonymousType` ``` List<object> someList = new List<object>(); someList.Add(new { foo = 1 }); ``` My problem is that I can't make it stronly typed to do something like this: ``` someList.Where(x=> x.foo == 1); ``` However, it's possible on this list: ``` var someList = new[] { new { foo = 1 } }; ``` Can I cast my first list to make it behave like the second list? I want to be able to use lambda expressions on the properties like I showed above.

Original source

Related problems