将匿名类型转换为动态对象列表

问题描述:

为什么我无法将List<AnonymousObject>转换为List<dynamic>?我有这样的下面的代码:将匿名类型转换为动态对象列表

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

然后我访问GridView.DataSource用下面的代码:

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

但在这里我将它转换为List<dynamic>行抛出一个错误,它说:

无法投射类型为System.Collections.Generic.List'1[<>f__AnonymousType0'8[System.Int32,System.String]]的对象至System.Collections.Generic.List'1[System.Object]

为什么我不能投匿名类型的列表到dynamic,或者作为错误到object型说?我该如何解决这个问题?我的代码是在C#中,框架4.0,内置VS2010 Pro,平台是ASP.NET。

请帮助,在此先感谢。

由于List<T>在变,没有共同的变体,所以你必须IEnumerable<dynamic>支持共同变异:

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

更多information about covariant

+1

不要忘记加上'使用System.Linq;'在你的文件头中,如果你还没有 – 2014-07-18 15:48:13

首先,与一般的铸造不这样工作。此演员表无效:

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

原因是List不是co-variant。如果是这样,你可以source2.Add(source2);,并且当source1只包含字符串时,它会自己包含它自己。

其次,Anonymous types只是具有只读属性和值相等语义的编译器声明类。如果您创建了只读属性和值相等语义的类,那么您的类将与匿名类型相同,除非您的类型具有开发人员确定的名称,而匿名类型具有编译器确定的名称。匿名类型并不特殊。

第三,dynamic变量是绕过编译器类型检查的一种方法。他们不会绕过运行时类型检查。您可以使用c#的转换语法来显式地将类型转换为动态...注意:这不是一个强制转换!您无法将运行时转换为运行时不存在的类型。

但是,包含动态类型表达式的操作未被编译器解析或类型检查。编译器将有关该操作的信息打包在一起,并且该信息稍后用于在运行时评估操作。作为该过程的一部分,dynamic类型的变量被编译为object类型的变量。因此,动态类型仅在编译时存在,而不是在运行时存在。

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 

最后,如果你仍然想List<dynamic>,做到这一点:

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

但是你可以很容易地做到这一点:

var anonList = GetAnonList(); 
List<object> objectList = anonList.Cast<object>().ToList(); 
+0

太棒了,这对我很有用! – 2018-02-01 19:13:31