【问题标题】:Cast List of Anonymous type to List of Dynamic Objects将匿名类型列表转换为动态对象列表
【发布时间】:2013-04-24 03:38:37
【问题描述】:

为什么我不能将 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&lt;dynamic&gt; 的行上抛出了一个错误,它说:

无法将 System.Collections.Generic.List'1[&lt;&gt;f__AnonymousType0'8[System.Int32,System.String]] 类型的对象转换为 System.Collections.Generic.List'1[System.Object] 类型。

为什么我不能将匿名类型列表转换为dynamic,或者如错误所说的object 类型?我该如何解决这个问题?

我的代码是C#,框架4.0,构建在VS2010 Pro,平台是ASP.NET。

请帮忙,提前谢谢。

【问题讨论】:

    标签: c# .net-4.0 anonymous-types


    【解决方案1】:

    由于List&lt;T&gt; 是同变的,而不是协变的,因此您必须将转换 转换为支持协变的IEnumerable&lt;dynamic&gt;

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

    了解更多information about covariant

    【讨论】:

    • 不要忘记添加“使用 System.Linq;”在您的文档标题中,以防您还没有
    【解决方案2】:

    首先,使用泛型进行强制转换不起作用。此演员表无效:

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

    原因是 List 不是协变的。如果是的话,你可以source2.Add(source2); 并且突然 source1 包含自己,而它应该只有字符串。

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

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

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

    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&lt;dynamic&gt;,请执行以下操作:

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

    但您也可以轻松做到这一点:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多