铸造匿名类型的列表,以动态对象的名单(Cast List of Anonymous type to List of Dynamic Objects)

为什么我不能投了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临,平台是ASP.NET。

请帮帮忙,在此先感谢。

Answer 1:

由于List<T>是变的,不共变体中,所以你必须浇注IEnumerable<dynamic>支持共变体:

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

欲了解更多有关信息,协变



Answer 2:

首先,与一般的铸造不工作的方式。 这种转换是无效:

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

其原因是,名单是不是共同的变体。 如果是这样,你可以source2.Add(source2); 突然来源1包含本身时,它应该只有字符串。

其次, 匿名类型只是编译器声明的只读属性和价值的平等语义类。 如果创建了具有只读属性和价值的平等语义类,类将是相同的匿名类型,除了你的类型将有一个开发人员确定的名字,而匿名类型都有一个编译器确定名称。 匿名类型不特殊。

第三, 动态变量的方式去解决编译器的类型检查。 他们不会到处运行时类型检查。 您可以使用C#铸造语法类型显式转换为动态...注意:这是不是一个投地! 你不能做投到在运行时不存在的类型运行。

但是,包含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

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

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

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

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