动态转换为List <T>

Bro*_*ing 6 c# generics dynamic

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

private static void FilterAndSortDataList<T>(List<T> dataList)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

调用FilterAndSortDataList时出现运行时绑定错误。有没有办法List<T>在运行时将我的dynamicList强制转换为?

请注意,FetchData()包含在插件中,所以我事先不知道T是什么类型。

naw*_*fal 7

我看不出它应该失败的原因,除非FetchData是不正确的数据。

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

可能性二:FetchData没有返回正确的List<T>对象。

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

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

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

   //throw; //better meaning here.
}
Run Code Online (Sandbox Code Playgroud)

它检查返回的类型是否是IEnumerable(希望它是一些IEnumerable<T>- 我们无法检查它是否是IEnumerable<T>它本身,因为我们没有T。这是一个不错的假设)在这种情况下,我们将获得的序列转换为List<T>,只是为了确保我们正在传递一个List<T>dynamic不适用于扩展方法,所以我们不得不调用Enumerable.ToList。如果dynamicList为 null 或不是可枚举,它会抛出比某些运行时绑定错误更好的含义。


D S*_*ley 0

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

我不知道为什么当它必须是 a 时你将其声明为动态List<T>,但我猜这是因为你不知道它T是什么。如果你这样做了,你可以直接投射它:

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

private static void FilterAndSortDataList<T>(List<T> dataList)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

GetData另一种选择也可能是通用的:

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

private static void FilterAndSortDataList<T>(List<T> dataList)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • @RobertHarvey 他是否知道编译时的类型并不重要,因为他使用的是“dynamic”。显然,实际值是一个数组或字符串或不是任何类型的列表的东西,因为它失败了。如果它是任何类型的列表,即使他在编译时不知道通用参数,那么他的代码也会工作。 (2认同)