考虑一下这代码:
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.IndexOf的代码让我更加好奇,因为它正在移植到Array.IndexOf。
发布于 2017-07-09 02:38:34
数组类调用方法中IndexOf的实现:
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);UPD:我写了一篇关于这个问题的小文章:http://blog.rogatnev.net/2017/07/14/IndexOf-with-IEquatable.html
发布于 2017-07-09 02:33:41
因为泛型对象集合在测试Contains、IndexOf、LastIndexOf和Remove等方法中是否相等时使用了IndexOf接口。
数组对<T>一无所知,所以它不能实现或使用IEquatable接口。
数组只保存非泛型的对象。它将调用Equals将一个对象与另一个对象进行比较,因为所有对象都有一个可以随意重写的Equals方法。
发布于 2017-07-09 02:35:22
List<T>可以使用IEquatable<T>接口,这样就可以像预期的那样工作。
数组使用的是来自Equals的Object方法,而不是覆盖该方法,而只是实现IEquatable。
尝试定义Equals如下:
public override bool Equals(Object other) => other != null && (other as Item).Id == Id;这对两种情况都有同样的效果。
https://stackoverflow.com/questions/44992402
复制相似问题