简体   繁体   中英

Cast List of Anonymous type to List of Dynamic Objects

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM