为什么Array.IndexOf没有像List <t>那样检查IEquatable呢?

时间:2017-07-09 02:21:39

标签: c# .net collections indexof iequatable

考虑this代码:

public static void Main()
{
    var item = new Item { Id = 1 };

    IList list = new List<Item> { item };
    IList array = new[] { item };

    var newItem = new Item { Id = 1 };

    var lIndex = list.IndexOf(newItem);
    var aIndex = array.IndexOf(newItem);

    Console.WriteLine(lIndex);
    Console.WriteLine(aIndex);
}

public class Item : IEquatable<Item>
{
    public int Id { get; set; }

    public bool Equals(Item other) => other != null && other.Id == Id;

}

结果:

0
-1

为什么List<T>Array之间的结果有所不同?我想这是设计的,但为什么呢?

查看List<T>.IndexOf的代码让我更加疑惑,因为它正在移植到Array.IndexOf

3 个答案:

答案 0 :(得分:4)

因为在IEquatable<T>ContainsIndexOfLastIndexOf等方法中测试相等性时,通用对象集合使用Remove接口。

Array对<T>一无所知,因此无法实现或使用IEquatable接口。

数组反而包含非通用的对象。它将调用Equals将一个对象与另一个对象进行比较,因为所有对象都有Equals方法,您可以自由覆盖它。

答案 1 :(得分:4)

在数组类调用方法中实现public static int IndexOf(Array array, object value, int startIndex, int count)

object

如您所见,它使用object obj = objArray[index]; if (obj != null && obj.Equals(value)) return index; 作为值参数。在这种方法中有代码:

public virtual bool Equals(object obj)

类适用于对象,因此它调用List方法,而不是通用方法。

IndexOfpublic static int IndexOf<T>(T[] array, T value, int startIndex, int count) 中使用通用实施:

EqualityComparer<T>.Default.IndexOf(array, value, startIndex, count);

因此,它使用通用质量比较器:

import java.util.Scanner;
public class count

{
  public static void main(String[] args) {
    int s, e, c = 0, sum = 0,i=1;
    Scanner sc = new Scanner(System.in);
    System.out.print("Enter a starting number:  ");
    s = sc.nextInt();
    System.out.print("Enter an end number:  ");
    e = sc.nextInt();
    System.out.print("Enter a count by number:  ");
    c = sc.nextInt();

    {
      for (i=s; i <= e; i+=c)
        sum += i;
      System.out.println("Sum of your numbers  " + sum);

    }

  }
}

UPD :我写了一篇关于此问题的帖子:http://blog.rogatnev.net/2017/07/14/IndexOf-with-IEquatable.html

答案 2 :(得分:2)

List<T>可以使用IEquatable<T>接口,以便按预期工作。

数组正在使用Equals中的Object方法,您并未覆盖该方法,而只是实施IEquatable

尝试定义Equals,如:

public override bool Equals(Object other) => other != null && (other as Item).Id == Id;

这对两种情况都有同样的作用。