如何使用C# LINQ从MyObject对象列表中移除MyType属性存在于指定字符串列表中的对象
先把你的基础定义列出来方便对照:
public class MyObject { public int Id { get; set; } public string MyType { get; set; } } public List<MyObject> MyObjectList { get; set; } public List<string> MyTypeList { get; set; }
先说说你之前尝试的问题
第一个代码:
MyObjectList.Select(i => i.MyType).Except(MyTypeList).ToList()
这里Select把MyObject转换成了string(只提取了MyType属性),最后得到的是List<string>,完全不是你想要的List<MyObject>,方向就错了。第二个代码:
MyObjectList.Where(i => i.MyType.Except(MyTypeList))i.MyType是单个字符串,Except是集合之间的差集操作,单个字符串没法直接和List<string>用Except,语法本身就不成立,编译器直接会报错。
两种正确的实现方式
方式一:Where + !Contains(兼容所有.NET版本)
这是最直观的写法,核心逻辑是筛选出MyType不在MyTypeList里的对象:
List<MyObject> MyObjectListNEW = MyObjectList .Where(obj => !MyTypeList.Contains(obj.MyType)) .ToList();
简单说就是遍历MyObjectList的每个对象,判断它的MyType是否不在目标排除列表里,留下符合条件的对象再转成列表。
方式二:ExceptBy(.NET 6及以上版本推荐)
如果你的项目用的是.NET 6或更高版本,强烈推荐用ExceptBy——这是官方专门为「按指定键排除集合元素」设计的方法,性能比Where+Contains更优(尤其是当MyTypeList元素很多时):
List<MyObject> MyObjectListNEW = MyObjectList .ExceptBy(MyTypeList, obj => obj.MyType) .ToList();
它的逻辑更直接:以MyObject的MyType作为匹配键,排除所有键存在于MyTypeList中的对象,直接得到剩余的MyObject集合。
性能优化小技巧
如果MyTypeList的元素数量很大,建议先把它转换成HashSet<string>,这样Contains的查找速度会从O(n)降到O(1),处理大集合时效率提升明显:
var myTypeHashSet = new HashSet<string>(MyTypeList); List<MyObject> MyObjectListNEW = MyObjectList .Where(obj => !myTypeHashSet.Contains(obj.MyType)) .ToList();
内容的提问来源于stack exchange,提问作者A Bogus

