考虑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
。
答案 0 :(得分:4)
因为在IEquatable<T>
,Contains
,IndexOf
和LastIndexOf
等方法中测试相等性时,通用对象集合使用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
方法,而不是通用方法。
在IndexOf
班public 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;
这对两种情况都有同样的作用。