我有这个类(部分列表):
class CiscoSwitch
{
private string _SwitchName = string.Empty;
public SwitchName {get {return _SwitchName;} set{_SwitchName=value; }}
}
我有 2 个 CiscoSwitch 对象列表。我正在尝试比较它们以挑选出不重复的那些。我只想要副本。我尝试了一个 Lambda 表达式,但得到一个编译器错误,指出 CiscoSwitch 是一个非委托(delegate)类型。
我现在想知道这样的事情 - 它允许我使用 List.Except() 方法(我认为):
static class SwitchComparer
{
static bool CompareSwitchNames(CiscoSwitch s1, CiscoSwitch s2)
{
if (sw1.SwitchName == s2.SwitchName) {return true;}
else {return false;}
}
}
// to find the differences
// this is a method of the CiscoSwitchClass
private List<CiscoSwitch> FindDifferences(List<CiscoSwitch> List1, List<CiscoSwitch> List2)
{
return List1.Except(List2, SwitchComparer.CompareSwitchNames();
}
这也可以用 foreach 来完成,但我认为这种方法如果正确的话会更简洁。我也在想,有一天我可能想比较 CiscoSwitch 的其他属性,因此可以在需要时向 SwitchComparer 类添加方法。
最佳答案
不,只有一个这样的方法对您没有帮助。你需要实现一个 IEqualityComparer<CiscoSwitch>
传递给 Enumerable.Except
- 即便如此,您的代码也需要:
return List1.Except(List2, new SwitchComparer()).ToList();
覆盖 Equals
和 GetHashCode
在 CiscoSwitch
内虽然会更自然地完成这个技巧 - 理想情况下你应该实现 IEquatable<CiscoSwitch>
也是。
但是,值得注意的是像这样的可变 类型不能很好地与Dictionary<,>
之类的东西一起玩。 - 如果在将对象作为键插入字典后以影响其哈希码的方式更改对象,您将无法再次访问它。如果可以,请考虑使类型不可变。
还有几点需要注意:
任何时候你写:
if (condition) { return true; } else { return false; }
你应该写远更简单的:
return condition;
所以你的
CompareSwitchNames
方法是:static bool CompareSwitchNames(CiscoSwitch s1,CiscoSwitch s2) { 返回 s1.SwitchName == s2.SwitchName;
FindDifferences
的参数名称应遵循 .NET 命名约定(例如list1
和list2
)- 使用
Except
只会找到第一个列表中不在第二个列表中的元素;如果您需要找到对称差异,请考虑使用HashSet<T>
明确地。
编辑:如果你想有多种比较方式,你可以这样:
public static class SwitchComparers
{
public static readonly IEqualityComparer<CiscoSwitch> ByName =
new ByNameComparer();
public static readonly IEqualityComparer<CiscoSwitch> ByCost =
new ByCostComparer();
private sealed class ByNameComparer : IEqualityComparer<CiscoSwitch>
{
// Implementation
}
private sealed class ByCostComparer : IEqualityComparer<CiscoSwitch>
{
// Implementation
}
}
关于c# - 找出集合中的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9638093/