我有一个名为BaseViewModel
的类,并且有多个类从其继承。
我有一个List<BaseViewModel>
,其中包含所有子类,而不是单个BaseViewModel
。
现在,我想从DateViewModel
中提取特定类型的所有类,例如我的List<BaseViewModel>
。
现在,我正在执行此操作,并抛出一个InvalidCastException
:CustomFieldViewModels
是我的List<BaseViewModel>
,其中有一个ControlType
枚举,用于识别所有“孩子”。
public List<DateViewModel> DateCustomViewModels
{
get
{
return (List<DateViewModel>)CustomFieldViewModels
.Where(x => x.ControlType == CustomFieldControlValueType.Date);
}
}
我对Linq不太熟悉,我不确定自己做错了什么。
我也很确定执行
foreach
并填充List<DateViewModel>
并不是很好的性能,也不是很干净。据我了解,
.Where
将返回我所问的任何内容的List
,并带有一个过滤器(这里是我的枚举)。我不明白为什么由于我的所有孩子都从父类继承而导致转换时遇到麻烦,而且我在过滤中没有使用孩子专用的元素。同样,即使主列表的类型是Base,其所有元素都不是Base类型,因此,一开始就不应该进行任何强制转换。我感觉好像缺少了非常明显的东西,但我看不到,非常欢迎您提供任何帮助。
如果您提供答案,不妨给出一个简短的解释,而不仅仅是复制粘贴代码,将不胜感激:)
编辑:为了显示最终结果,我选择了各种答案,因为我不需要列表,但仍然需要类型。
public IEnumerable<DateControlViewModel> DateCustomViewModels
{
get
{
return CustomFieldControlViewModels.OfType<DateControlViewModel>();
}
}
最佳答案
您需要使用OfType()
:
public List<DateViewModel> DateCustomViewModels
{
get
{
return CustomFieldViewModels.OfType<DateViewModel>().ToList()
}
}
据我了解,.Where会传回我所有的清单
用过滤器问(这里是我的枚举)
不,它将返回
IEnumerable<BaseViewModel>
。您在Where()
中指定的条件不会更改返回类型,它仅指定将包括哪些BaseViewModel
对象。我不明白为什么我的孩子们在投球时会遇到麻烦
从父类继承,并且我没有使用针对孩子的
过滤中的元素。
即使
DateViewModel
继承自BaseViewModel
,您也无法将其从List<DateViewModel>
显式转换为List<BaseViewModel>
,因为List<T>
是invariant。另外,即使主列表的类型为Base,也不会
元素属于基本类型,因此不应进行任何强制转换
首先。
您是对的,不需要强制转换。使用
OfType<DateViewModel>()
将仅返回DateViewModel
的对象。而且,返回的集合现在是IEnumerable<DateViewModel>
(不再是List<BaseViewModel>
),并且编译器可以验证其与DateCustomViewModels
属性的返回类型兼容。见MSDN