我有一个名为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

10-06 06:34