在C#中,我有一个 MyObj 类实现了一个接口 IMyInterface 。
我现在有一组MyObj类的列表:
IEnumerable<List<MyObj>> myObjGroups
我希望将其转换/转换为
IEnumerable<List<IMyInterface>> myInterfaceGroups
我尝试的所有内容都抛出异常。
类型&#39; System.InvalidCastException&#39;发生在System.Core.dll中但未在用户代码中处理 附加信息:无法转换类型&System; Series.Collections.Generic.List`1 [MyObj]&#39;输入&#39; System.Collections.Generic.List`1 [IMyInterface]&#39;。
我试过了:
IEnumerable<List<IMyInterface>> myInterfaceGroups= new List<List<IMyInterface>>(myObjGroups.Cast<List<IMyInterface>>());
和
IEnumerable<List<IMyInterface>> myList = myObjGroups.Cast<List<IMyInterface>>();
并且两者似乎都在运行时抛出异常。
关于我做错了什么建议?
答案 0 :(得分:2)
尝试以下方式:
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>
答案 1 :(得分:0)
你做错了什么。您无法将IEnumerable
投射到List
。列表是一个实际的metrialized数据集合,而运行时IEnumerable
需要迭代才能检索数据。
要解决您的问题,您需要转换为IEnumerable<IMyInterface>
:
检查工作小提琴: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());
}
}