【问题标题】:Cast dynamic to List<T>将动态转换为 List<T>
【发布时间】:2013-08-09 16:03:47
【问题描述】:
private static void GetData()
{
   dynamic dynamicList =FetchData();
   FilterAndSortDataList(dynamicList);
}

private static void FilterAndSortDataList<T>(List<T> dataList)
{
    ...
}

我在调用 FilterAndSortDataList 时遇到运行时绑定错误。有没有办法在运行时将我的 dynamicList 转换为 List&lt;T&gt;

注意 FetchData() 是由插件实现的,所以我事先并不知道 T 是什么类型。

【问题讨论】:

  • 它实际上需要成为一个列表才能工作。它给出该错误的事实意味着该对象实际上不是一个列表。
  • 这里可能有一些帮助:stackoverflow.com/q/5014235 和这里:stackoverflow.com/questions/513952
  • dynamic 变量中实际存在什么样的对象?换句话说,FetchData() 返回什么?

标签: c# generics dynamic


【解决方案1】:

我看不出它为什么会失败,除非FetchData 是不正确的数据。

可能性一:FetchData 返回 null,因此无法计算类型参数(null 在 C# 中没有类型)。

可能性二:FetchData 没有返回正确的 List&lt;T&gt; 对象。

我会重新设计这样的东西:

private static void GetData()
{
   dynamic dynamicList = FetchData();

   if (dynamicList is IEnumerable) //handles null as well
       FilterAndSortDataList(Enumerable.ToList(dynamicList));

   //throw; //better meaning here.
}

它检查返回的类型是否为IEnumerable(希望它是一些IEnumerable&lt;T&gt; - 我们无法检查它本身是否是IEnumerable&lt;T&gt;,因为我们没有T。这是一个不错的假设)其中如果我们将获得的序列转换为List&lt;T&gt;,只是为了确保我们传递了List&lt;T&gt;dynamic 不能与扩展方法一起使用,所以我们不得不打电话给 Enumerable.ToList。如果dynamicList 为空或不是它抛出的可枚举,这比一些运行时绑定错误更有意义。

【讨论】:

    【解决方案2】:

    有没有办法在运行时将我的动态列表转换为列表

    我不知道为什么当它必须是 List&lt;T&gt; 时你将它声明为动态的,但我猜这是因为你不知道 T 是什么。如果你做了,你可以直接投射它:

    private static void GetData()
    {
       dynamic dynamicList = new List<string> ();
       FilterAndSortDataList((List<string>)dynamicList);
    }
    
    private static void FilterAndSortDataList<T>(List<T> dataList)
    {
        ...
    }
    

    但显然这可能会在运行时失败。

    另一种选择可能是将GetData 也设为通用:

    private static void GetData<T>()
    {
       List<T> list = new List<T>();
       FilterAndSortDataList(list);
    }
    
    private static void FilterAndSortDataList<T>(List<T> dataList)
    {
        ...
    }
    

    【讨论】:

    • dynamic dynamicList = new List&lt;string&gt; (); 之后的 dynamicList 是 List&lt;string&gt; 并且不需要转换。
    • @HamletHakobyan:是的,我认为 D 的观点是元素类型在编译时是未知的。
    • @RobertHarvey 如果您在编译时不知道元素类型,则无法直接转换它。 :)
    • @HamletHakobyan:确实如此。但是有一些魔术可能会奏效;请参阅我在 OP 下方发布的 cmets。
    • @RobertHarvey 在编译时是否知道类型并不重要,因为他使用的是dynamic。显然,实际值是一个数组或一个字符串,或者不是任何类型的列表,因为它失败了。如果它是任何类型的列表,即使他在编译时不知道通用参数,那么他的代码也可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2012-02-24
    • 2012-02-14
    • 1970-01-01
    相关资源
    最近更新 更多