c# - 在 C# 中,为什么从对象列表到接口(interface)列表的转换会引发异常?

标签 c# collections casting covariance

在 C# 中,我有一个类 MyObj,它实现了一个接口(interface) IMyInterface

我现在有一个 MyObj 类列表的集合:

IEnumerable<List<MyObj>> myObjGroups

我想将其转换/转换为

IEnumerable<List<IMyInterface>> myInterfaceGroups

我尝试过的所有操作都抛出了异常。

System.Core.dll 中发生“System.InvalidCastException”类型的异常,但未在用户代码中处理 其他信息:无法将“System.Collections.Generic.List`1[MyObj]”类型的对象转换为“System.Collections.Generic.List`1[IMyInterface]”类型。

我已经尝试过:

IEnumerable<List<IMyInterface>> myInterfaceGroups= new List<List<IMyInterface>>(myObjGroups.Cast<List<IMyInterface>>());

和:

IEnumerable<List<IMyInterface>> myList = myObjGroups.Cast<List<IMyInterface>>();

两者似乎都会在运行时抛出异常。

对我做错了什么有什么建议吗?

最佳答案

尝试以下方法:

IEnumerable<List<IMyInterface>> myInterfaceGroups = myObjGroups
    .Select(l => l.Select(o => (IMyInterface)o).ToList());

或者如果您更喜欢使用 Cast<T>()扩展方法:

IEnumerable<List<IMyInterface>> myInterfaceGroups = myObjGroups
    .Select(l => l.Cast<IMyInterface>().ToList());

编辑:一些解释

为了更好地了解您为何获得 InvalidCastException异常(exception),让我们尝试分解你的原始表达式:

IEnumerable<List<IMyInterface>> myInterfaceGroups = 
    new List<List<IMyInterface>>(myObjGroups.Cast<List<IMyInterface>>());

这相当于:

IEnumerable<List<IMyInterface>> myObjGroupsAsInterfaceList = myObjGroups
    .Cast<List<IMyInterface>>()
    .ToList();

IEnumerable<List<IMyInterface>> myInterfaceGroups = new List<List<IMyInterface>>(myObjGroupsAsInterfaceList);

Cast<T>()扩展方法只是迭代项目并尝试将每个项目转换为类型 T 。我们可以替换 Cast<T>() 的功能扩展方法结合ToList<T>()包含以下代码片段:

List<List<IMyInterface>> myObjGroupsAsInterfaceList = new List<List<IMyInterface>>();
foreach (List<MyObj> myObjGroup in myObjGroups)
{
    List<IMyInterface> myObjGroupAsInterface = myObjGroup; // Compile error!
    myObjGroupsAsInterfaceList.Add(myObjGroupAsInterface);
}

所以根本问题是你不能分配 List<MyObj>对象为 List<IMyInterface> 类型的变量。

要找到有关为什么上述不可能的更多解释,请查看以下问题:C# variance problem: Assigning List<Derived> as List<Base>

关于c# - 在 C# 中,为什么从对象列表到接口(interface)列表的转换会引发异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40704188/

相关文章:

c# - 在 xaml 中使用自定义 RoutedUICommand 会引发异常

c# - 通过 Excel-DNA 将 Excel.Range 从 VBA 传递到 C#

c# - 从 Dictionary<Key, Item> 中移除元素

java - 将 priorityQueue 更改为最大优先级队列

C# dll 中的 C# 转换异常

c# - 我怎样才能得到一个文件的路径?

c# - 在 .NET ASMX 网络服务中获取 session

使用集合时线程安全的 C# 最佳实践(还不是并发的)

arrays - 如何将元组的快速数组转换为 NSMutableArray?

c# - 网络应用程序的设计帮助?