寻找集合中的差异

Dav*_*een 1 c#

我有这个类(部分列表):

class CiscoSwitch 
{
  private string _SwitchName = string.Empty;
  public SwitchName {get {return _SwitchName;} set{_SwitchName=value; }}
}
Run Code Online (Sandbox Code Playgroud)

我有两个CiscoSwitch对象列表.我试图比较它们来挑选那些不重复的.我只想要重复.我尝试了一个Lambda表达式,但得到了一个编译器错误,即CiscoSwitch是非delgate类型.

我现在想知道这样的事情 - 它允许我使用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();
 }
Run Code Online (Sandbox Code Playgroud)

这也可以用foreach完成,但我认为这种方式更清晰,如果它是正确的.我也在想有一天我可能想比较一下CiscoSwitch的其他属性,所以可以根据需要在SwitchComparer类中添加方法.

Jon*_*eet 5

不,只是有一个这样的方法对你没有帮助.你需要实现一个IEqualityComparer<CiscoSwitch>传递给Enumerable.Except- 甚至那时你的代码需要是:

return List1.Except(List2, new SwitchComparer()).ToList();
Run Code Online (Sandbox Code Playgroud)

覆盖EqualsGetHashCode内部CiscoSwitch将更自然地做到这一点 - 理想情况下你也应该实现IEquatable<CiscoSwitch>.

但是,值得注意的是,像这样的可变类型不能很好地处理类似的事情Dictionary<,>- 如果在将对象作为键插入字典后以某种方式更改对象的哈希代码,则不会能够再次得到它.如果可以,请考虑使类型不可变.

还有几点需要注意:

  • 你写的任何时候:

    if (condition)
    {
        return true;
    }
    else
    {
        return false;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    则应该写远远简单:

    return condition;
    
    Run Code Online (Sandbox Code Playgroud)

    所以你的CompareSwitchNames方法是:

    static bool CompareSwitchNames(CiscoSwitch s1,CiscoSwitch s2){return s1.SwitchName == s2.SwitchName; }

  • 您的参数名称FindDifferences应遵循.NET命名约定(例如list1list2)

  • 使用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
    }
}
Run Code Online (Sandbox Code Playgroud)