见 - IEnumerable<T>.Contains with predicate
那些采用“谓词”(表示匹配的布尔函数)的函数可以让您进行更复杂的检查。在这种情况下,您可以使用它们来比较子属性而不是顶级对象。
新代码将如下所示:
foreach (DirectoryInfo path in currDirs) {
if (!newDirs.Any(newDir => newDir.Name == path.Name)) {
// TODO: print your error message here
currNoPairs.Add(path.Name);
}
}
回复您的评论:
好的,我明白了,但是 any 和 contains 之间的区别是什么?
List<T>.Contains
此方法遍历列表中的每个项目,查看该项目是否等于您传入的值。
这个方法的代码看起来有点像这样(这里为了说明而简化了):
for(var item in yourList) {
if(item.Equals(itemYouPassedIn) {
return true;
}
}
return false;
如您所见,它只能比较顶级项目。它不检查子属性,除非您使用覆盖默认 Equals 方法的自定义类型。由于您使用的是内置的 DirectoryInfo 类型,因此您无法在不创建自定义派生类的情况下覆盖此 Equals 行为。由于有更简单的方法可以做到这一点,我不会推荐这种方法,除非你需要在很多不同的地方这样做。
IEnumerable<T>.Any
此方法遍历列表中的每个项目,然后将该项目传递给您传入的“谓词”函数。
这个方法的代码看起来有点像这样(为了说明而简化):
for(var item in yourList) {
if(isAMatch(item)) { // Note that `isAMatch` is the function you pass in to `Any`
return true;
}
}
return false;
您的谓词函数可以像您希望的那样复杂,但在这种情况下,您只需使用它来检查子属性是否相等。
// This bit of code defines a function with no name (a "lambda" function).
// We call it a "predicate" because it returns a bool, and is used to find matches
newDir => newDir.Name == path.Name
// Here's how it might look like if it were defined as a normal function -
// this won't quite work in reality cause `path` is passed in by a different means,
// but hopefully it makes the lambda syntax slightly more clear
bool IsAMatch(DirectoryInfo newDir) {
return newDir.Name == path.Name;
}
由于您可以在每个使用它的地方自定义此谓词,因此这可能是一个更好的策略。我建议您使用这种样式,直到您在代码中的许多地方进行精确检查,在这种情况下,自定义类可能会更好。