简体   繁体   English

将匿名类型的强制列表列表到动态对象列表

[英]Cast List of Anonymous type to List of Dynamic Objects

Why can't I cast a List<AnonymousObject> to a List<dynamic> ? 为什么我不能将List<AnonymousObject>转换为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: 然后我使用以下代码访问GridView.DataSource

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

But it throws an error on the line where I cast it to List<dynamic> , it says: 但它在我将其转换为List<dynamic>的行上抛出了一个错误,它说:

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] . 无法将类型为System.Collections.Generic.List'1[<>f__AnonymousType0'8[System.Int32,System.String]]对象System.Collections.Generic.List'1[<>f__AnonymousType0'8[System.Int32,System.String]]转换为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? 为什么我不能将匿名类型列表转换为dynamic ,或者将错误描述为object类型? How can I resolve this? 我该如何解决这个问题?

My Code is in C#, framework 4.0, build in VS2010 Pro, platform is ASP.NET. 我的代码是在C#,框架4.0,在VS2010 Pro中构建,平台是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: 由于List<T>是变的,不共变体中,所以你必须浇注IEnumerable<dynamic>支持共变体:

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. 原因是List不是共变体。 If it were, you could source2.Add(source2); 如果是,你可以source2.Add(source2); and suddenly source1 contains itself when it should only have strings. 当它应该只有字符串时,突然source1包含自己。

Secondly, Anonymous types are just compiler declared classes with readonly properties and value equality semantics. 其次, 匿名类型只是编译器声明的类,具有readonly属性和值相等语义。 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. 如果您创建了一个具有readonly属性和值相等语义的类,则您的类将与匿名类型相同,除非您的类型具有开发人员确定的名称,而匿名类型具有编译器确定的名称。 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! 您可以使用c#casting语法将类型显式转换为动态...注意:这不是强制转换! 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. 但是,包含dynamic类型表达式的操作不会被编译器解析或进行类型检查。 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. 作为过程的一部分,dynamic类型的变量被编译为object类型的变量。 Therefore, type dynamic exists only at compile time, not at run time. 因此,类型dynamic仅在编译时存在,而不是在运行时存在。

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: 最后,如果您仍然需要List<dynamic> ,请执行以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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