【问题标题】:List always does not contain array even it is列表总是不包含数组,即使它是
【发布时间】:2015-04-24 19:27:14
【问题描述】:

我正在尝试检查数组列表是否包含具有相反顺序的因子的数组,如果没有,则添加它们:

var faclist = new List<int[]>();
var factors = new int[2] {i, j};
if (!faclist.Contains(factors.Reverse()))
{
     faclist.Add(factors);
}

但是,即使存在具有相反因子的数组,此代码也总是不正确。

【问题讨论】:

    标签: c# arrays list contain


    【解决方案1】:

    .Contains 适用于 .Equals 方法。默认情况下,.Equals 方法仅返回 true,如果两个实例(引用)相同。

    解决这个问题的一种可能方法 - 如果因素的数量是固定的 - 是使用Tuple&lt;int,int&gt;。您可以在 `Tuple 类上定义 Reverse 方法:

    public static class Foo {
    
        public static Tuple<T2,T1> Reverse<T1,T2> (this Tuple<T1,T2> tuple) {
            return new Tuple<T2,T1>(tuple.Item2,tuple.Item1);
        }
    
    }
    

    然后简单地调用它:

    Tuple<int,int> t = new Tuple<int,int>(3,5);
    Tuple<int,int> t2 = t.Reverse();
    

    如果不是,您可以定义一个 wrapper 类,该类执行 here 所述的相等性检查。

    或者另一种选择是在.Contains 方法中自己提供一个相等检查器,如@xanatos answer 所述。

    演示:

    $ csharp
    Mono C# Shell, type "help;" for help
    
    Enter statements below.
    csharp> var t1 = new Tuple<int,int>(3,2);
    csharp> var t2 = new Tuple<int,int>(3,2); 
    csharp> t1.Equals(t2);
    true
    csharp> int[] t1 = new int[] {3,2};
    csharp> int[] t2 = new int[] {3,2}; 
    csharp> t1.Equals(t2);
    false
    

    【讨论】:

      【解决方案2】:

      正如 CommuSoft 所写,因为数组并没有像你想象的那样实现比较(它们只做参考比较)

      另一种解决方案是实现一个相等比较器:

      public class IntArrayComparison : IEqualityComparer<int[]> {
          public bool Equals(int[] x, int[] y) {
              if (x == null) {
                  return y == null;
              }
      
              if (y == null) {
                  return false;
              }
      
              return x.SequenceEqual(y);
          }
      
          public int GetHashCode(int[] obj) {
              throw new NotImplementedException();
          }
      }
      
      if (!faclist.Contains(factors.Reverse().ToArray(), new IntArrayComparison())) {
      

      然后在Contains 方法中使用它。 (注意我要把Reverse()的结果改回数组,因为Reverse()返回的是IEnumerable&lt;T&gt;

      【讨论】:

      • 太糟糕了,你不能像 this one 这样插入 Function&lt;T,T,Bool&gt;
      • 是的,但我想知道为什么他们不提供直接注入函数的方法。除了.Equals(好吧.GetHashCode)没有太多有用的额外功能......
      • @CommuSoft 也许他们想让程序员清楚比较的类型。假设我没有使用ToArray()factors.Reverse() 将是IEnumerable,因此它将为faclist 的每个元素“重建”。在这种情况下,这是一个便宜的操作,但如果它是一个由数据库“支持”的集合,那将是相当昂贵的。例如if (!faclist.Any(x =&gt; x.SequenceEqual(factors.Reverse())))
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 2019-01-25
      • 1970-01-01
      • 1970-01-01
      • 2021-07-26
      相关资源
      最近更新 更多