将List<DTO?>转换为List<DTO>时,使用Where过滤空值后提示类型不匹配的问题求助
哦,这个问题我之前也踩过坑!原因其实很简单——你虽然用Where过滤掉了null元素,但Where方法返回的仍然是IEnumerable<DTO?>(因为原集合的元素类型是可空的),编译器没办法自动把它转换成List<DTO>,所以才会报类型不匹配的错误。
给你几个可行的解决方案,按推荐程度排序:
方案1:使用OfType<DTO>()(最安全简洁)
这个方法会一步完成过滤null和类型转换的工作,它会自动跳过集合中的null元素,同时把非null元素的类型转换成DTO:
List<DTO?> items = new List<DTO?>(); List<DTO> notNullItems = items.OfType<DTO>().ToList();
方案2:结合Where和null原谅运算符!
如果你已经通过Where(c => c != null)确保了元素不会为null,可以用!(null原谅运算符)明确告诉编译器“这个元素肯定不是null”,之后再转换类型:
List<DTO?> items = new List<DTO?>(); List<DTO> notNullItems = items.Where(c => c != null).Select(c => c!).ToList();
在C# 9及以上版本,还可以用更直观的is not null语法:
List<DTO> notNullItems = items.Where(c => c is not null).Select(c => c!).ToList();
方案3:使用Cast<DTO>()(谨慎使用)
Cast<DTO>()会直接尝试把元素转换成非可空类型,但它不会自动过滤null——如果集合里还有漏网的null元素,运行时会抛出InvalidCastException。所以只有在你100%确定过滤后的元素都非null时才用这个方法:
List<DTO> notNullItems = items.Where(c => c != null).Cast<DTO>().ToList();
总的来说,方案1是最优选择,既不需要额外的断言,又能保证类型安全,编译器也能正确推断结果类型~
内容的提问来源于stack exchange,提问作者foad abdollahi
相关产品推荐
相关产品推荐

