Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast List of Anonymous type to List of Dynamic Objects

Tags:

Why can't I cast a List<AnonymousObject> to a List<dynamic>? I have this following code:

var datasource = someList.Select(o => new { x = o.A, y = o.B });
dgvSomeGridView.DataSource = datasource.ToList();
dgvSomeGridView.DataBind();

Then I access the GridView.DataSource with the following code:

var ds = ((List<dynamic>)dgvSomeGridView.DataSource);
....

But it throws an error on the line where I cast it to List<dynamic>, it says:

Unable to cast object of type System.Collections.Generic.List'1[<>f__AnonymousType0'8[System.Int32,System.String]] to type System.Collections.Generic.List'1[System.Object].

Why can't I cast a list of anonymous type to a dynamic, or as the error says to an object type? How can I resolve this?

My Code is in C#, framework 4.0, build in VS2010 Pro, platform is ASP.NET.

Please help, thanks in advance.

like image 999
John Isaiah Carmona Avatar asked Apr 24 '13 03:04

John Isaiah Carmona


People also ask

How to handle dynamic objects in c#?

You can create custom dynamic objects by using the classes in the System. Dynamic namespace. For example, you can create an ExpandoObject and specify the members of that object at run time. You can also create your own type that inherits the DynamicObject class.

How to dynamically create objects?

To create a new object dynamically, you use the "new" operator with the name of the class: local x = new QuantityOfWater; This creates a new object of the given class, returning a reference to the new object. You can now use the new object just like any other.

When you define an anonymous type the compiler converts that type into a?

The compiler generates a name for each anonymous type. If two or more anonymous type objects are defined in the same assembly and the sequence of properties are same in terms of names and types than the compiler treats both as same object instances of type.


2 Answers

Since List<T> is in-variant, not co-variant, so you have to cast into IEnumerable<dynamic> which supports co-variant:

var ds = ((IEnumerable<dynamic>)dgvSomeGridView.DataSource).ToList();

For more information about covariant

like image 52
cuongle Avatar answered Sep 29 '22 19:09

cuongle


Firstly, Casting with generic doesn't work that way. This cast is invalid:

List<string> source = GetStrings();
List<object> source2 = (List<object>) source;

The reason is that List is not co-variant. If it were, you could source2.Add(source2); and suddenly source1 contains itself when it should only have strings.

Secondly, Anonymous types are just compiler declared classes with readonly properties and value equality semantics. If you created a class with readonly properties and value equality semantics, your class would be the same as an anonymous type, except your type would have a developer determined name, while the anonymous type has a compiler determined name. Anon types are not special.

Thirdly, dynamic variables are a way to go around compiler type checking. They do not go around runtime type checking. You may use the c# casting syntax to explicitly convert the type to dynamic... note: this is not a cast! You cannot do a runtime cast to a type which does not exist at runtime.

However, operations that contain expressions of type dynamic are not resolved or type checked by the compiler. The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. As part of the process, variables of type dynamic are compiled into variables of type object. Therefore, type dynamic exists only at compile time, not at run time.

static void convertToDynamic()
{
    dynamic d;
    int i = 20;
    d = (dynamic)i;
    Console.WriteLine(d);

    string s = "Example string.";
    d = (dynamic)s;
    Console.WriteLine(d);

    DateTime dt = DateTime.Today;
    d = (dynamic)dt;
    Console.WriteLine(d);

}
// Results: 
// 20 
// Example string. 
// 2/17/2009 9:12:00 AM

Finally, if you still want a List<dynamic>, do this:

var anonList = GetAnonList();
List<dynamic> dynamicList = anonList.Select(x => (dynamic)x).ToList();

But you could just as easily do this:

var anonList = GetAnonList();
List<object> objectList = anonList.Cast<object>().ToList();
like image 43
Amy B Avatar answered Sep 29 '22 21:09

Amy B