我有这个类(部分列表):
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
}
}
