Gil*_*and 2 c# linq casting predicate
我有一个名为 的类BaseViewModel,以及从它继承的多个类。
我有一个List<BaseViewModel>包含所有子类,而不是单个BaseViewModel.
现在,我想提取特定类型的所有类,比如 my DateViewModel,从List<BaseViewModel>
现在我正在这样做,这会抛出一个InvalidCastException:
CustomFieldViewModels是 myList<BaseViewModel>它有一个ControlType枚举,我用它来识别所有“孩子”。
public List<DateViewModel> DateCustomViewModels
{
get
{
return (List<DateViewModel>)CustomFieldViewModels
.Where(x => x.ControlType == CustomFieldControlValueType.Date);
}
}
Run Code Online (Sandbox Code Playgroud)
我对 Linq 相当陌生,我不确定我做错了什么。
我也很确定执行 aforeach并填充 aList<DateViewModel>在性能方面没有那么好,也不是很干净。
据我了解,.Where它将返回一个List我所要求的,带有过滤器(这里是我的枚举)。我不明白为什么会出现问题,因为我所有的孩子都继承自父类,而且我没有在过滤中使用特定于孩子的元素。此外,即使主列表的类型是 Base,它的元素都不属于 Base 类型,因此首先不应该进行任何转换。
我觉得我错过了一些非常明显的东西,但我看不到它,非常欢迎任何帮助。
如果您提供答案,如果您能给出一个简短的解释而不仅仅是复制粘贴代码,我们将不胜感激:)
编辑:为了展示我最终做了什么,我选择了各种答案的混合,因为我不需要列表,但我仍然需要类型。
public IEnumerable<DateControlViewModel> DateCustomViewModels
{
get
{
return CustomFieldControlViewModels.OfType<DateControlViewModel>();
}
}
Run Code Online (Sandbox Code Playgroud)
您需要使用OfType():
public List<DateViewModel> DateCustomViewModels
{
get
{
return CustomFieldViewModels.OfType<DateViewModel>().ToList()
}
}
Run Code Online (Sandbox Code Playgroud)
据我了解, .Where 将返回一个包含我所要求的任何内容的列表,并带有一个过滤器(这里是我的枚举)
不,它会返回IEnumerable<BaseViewModel>。您在 中指定的条件Where()不会更改返回类型,它仅指定BaseViewModel将包含哪些对象。
我不明白为什么会出现问题,因为我所有的孩子都继承自父类,而且我没有在过滤中使用特定于孩子的元素。
即使DateViewModel继承自BaseViewModel,您也不能显式地强制转换为List<DateViewModel>,List<BaseViewModel>因为它List<T>是不变的。
此外,即使主列表的类型是 Base,它的元素都不属于 Base 类型,因此首先不应该进行任何转换。
你是对的,不需要铸造。使用OfType<DateViewModel>()它只会返回DateViewModel. 此外,返回的集合现在是IEnumerable<DateViewModel>(不再是List<BaseViewModel>)并且编译器可以验证它是否与DateCustomViewModels属性的返回类型兼容。
见MSDN