在 C# 中,为什么这种从对象列表到接口列表的转换会抛出异常?
In C#, why is this conversion from list of objects to list of interfaces throwing an exception?
在 C# 中,我有一个 class MyObj 实现了一个接口 IMyInterface.
我现在有一个 MyObj 列表集合 class:
IEnumerable<List<MyObj>> myObjGroups
我想将其转换/转换为
IEnumerable<List<IMyInterface>> myInterfaceGroups
而且我尝试的所有操作都引发了异常。
'System.InvalidCastException' 类型的异常发生在 System.Core.dll 但未在用户代码中处理
附加信息:无法将类型 '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
异常,让我们尝试分解您的原始表达式:
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>
你做错了什么。您不能将 IEnumerable
转换为 List
。列表是实际的数据集合,而 运行 次 IEnumerable
需要迭代才能检索数据。
要解决您的问题,您需要转换为 IEnumerable<IMyInterface>
:
检查工作 Fiddle:Here(下同)
public class Program
{
static IEnumerable<List<MyObj>> Get()
{
yield return new List<MyObj>();
yield return new List<MyObj>();
}
static void Main()
{
IEnumerable<List<MyObj>> myObjGroups = Get();
var result = myObjGroups.Cast<IEnumerable<IMyInterface>>();
foreach(var val in result)
Console.WriteLine(val.Count());
}
}
在 C# 中,我有一个 class MyObj 实现了一个接口 IMyInterface.
我现在有一个 MyObj 列表集合 class:
IEnumerable<List<MyObj>> myObjGroups
我想将其转换/转换为
IEnumerable<List<IMyInterface>> myInterfaceGroups
而且我尝试的所有操作都引发了异常。
'System.InvalidCastException' 类型的异常发生在 System.Core.dll 但未在用户代码中处理 附加信息:无法将类型 '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
异常,让我们尝试分解您的原始表达式:
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>
你做错了什么。您不能将 IEnumerable
转换为 List
。列表是实际的数据集合,而 运行 次 IEnumerable
需要迭代才能检索数据。
要解决您的问题,您需要转换为 IEnumerable<IMyInterface>
:
检查工作 Fiddle:Here(下同)
public class Program
{
static IEnumerable<List<MyObj>> Get()
{
yield return new List<MyObj>();
yield return new List<MyObj>();
}
static void Main()
{
IEnumerable<List<MyObj>> myObjGroups = Get();
var result = myObjGroups.Cast<IEnumerable<IMyInterface>>();
foreach(var val in result)
Console.WriteLine(val.Count());
}
}