List.Contains是否与List.IndexOf完全相当? [英] Is List.Contains fully comparison-wise equivalent to List.IndexOf?
问题描述
MSDN描述 List.Contains() 说明
该方法通过使用默认的相等比较器来确定相等性,如IEquatable.Equals方法的对象实现所定义对于T(列表中值的类型)。
和 List.IndexOf()表示
此方法使用默认的相等比较器EqualityComparer.Default来确定相等性,T为列表中值的类型。
和 EqualityComparer.Default 描述说明
Default属性检查类型T是否实现了System.IEq可用接口,如果是,则返回使用该实现的EqualityComparer。否则,它返回一个EqualityComparer,它使用由T提供的Object.Equals和Object.GetHashCode的重写。
这有点可疑 - 的描述只包含
提及 IEquatable
,并且可以放入不执行 IEquatable的东西转换为
列表
。
所以我猜他们只是使用相同的语义也许 Contains()
重用 IndexOf()
。
所以他们完全等价于比较明智吗?
简短回答:
- 否,
Contains()
不会重用IndexOf()
- 是的,它们是等效的比较明智的
我反编译(ReSharper)摘要 EqualityComparer< T> .Default.Equals(T x,T y)
方法。根据类型T初始化(并缓存) EqualityComparer< T>
的默认
实例。
List.Contains
EqualityComparer< T> @default = EqualityComparer< T> .Default;
// for循环
if(@ default.Equals(this._items [index],item))
return true;
List.IndexOf
return Array.IndexOf< T>(this._items,item,0,this._size);
Array.IndexOf
public static int IndexOf< T>(T [] array,T value,int startIndex,int count)
{
//某些断言
return EqualityComparer< T> .Default.IndexOf(array,value,startIndex,count);
}
EqualityComparer.IndexOf
内部虚拟int IndexOf(T []数组,T值,int startIndex,int计数)
{
// for循环
if(this.Equals(array [index],value))
return index;
}
这就是 EqualityComparer.Default 的实例
public static EqualityComparer< T>默认
{
获得
{
EqualityComparer< T> equalityComparer = EqualityComparer< T> .defaultComparer;
if(equalityComparer == null)
{
equalityComparer = EqualityComparer< T> .CreateComparer();
EqualityComparer< T> .defaultComparer = equalityComparer;
}
返回equalityComparer;
}
}
private static EqualityComparer< T> CreateComparer()
{
RuntimeType genericParameter1 =(RuntimeType)typeof(T); ((Type)genericParameter1 == typeof(byte))
return(EqualityComparer< T>)new ByteEqualityComparer();
if
//一些ifs继续
else
return(EqualityComparer< T>)new ObjectEqualityComparer< T>();
}
MSDN description of List.Contains() says
This method determines equality by using the default equality comparer, as defined by the object's implementation of the IEquatable.Equals method for T (the type of values in the list).
and the description of List.IndexOf() says
This method determines equality using the default equality comparer EqualityComparer.Default for T, the type of values in the list.
and EqualityComparer.Default description says
The Default property checks whether type T implements the System.IEquatable interface and, if so, returns an EqualityComparer that uses that implementation. Otherwise, it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T.
Which is kinda suspicious - the description of Contains
only mentions IEquatable
and it's possible to put stuff that does not implement IEquatable
into a List
.
So I'd guess they simply use the same semantics and perhaps Contains()
reuses IndexOf()
.
So are they fully equivalent comparison-wise?
Short answer:
- No,
Contains()
does not reuseIndexOf()
- Yes, they are equivalent comparison-wise
I decompiled (ReSharper) and saw that eventually both use abstract EqualityComparer<T>.Default.Equals(T x, T y)
method. The Default
instance for EqualityComparer<T>
is initialized (and cached) according to type T.
List.Contains
EqualityComparer<T> @default = EqualityComparer<T>.Default;
// for loop
if (@default.Equals(this._items[index], item))
return true;
List.IndexOf
return Array.IndexOf<T>(this._items, item, 0, this._size);
Array.IndexOf
public static int IndexOf<T>(T[] array, T value, int startIndex, int count)
{
// Some assertions
return EqualityComparer<T>.Default.IndexOf(array, value, startIndex, count);
}
EqualityComparer.IndexOf
internal virtual int IndexOf(T[] array, T value, int startIndex, int count)
{
// for loop
if (this.Equals(array[index], value))
return index;
}
And this is how EqualityComparer.Default is instantiated
public static EqualityComparer<T> Default
{
get
{
EqualityComparer<T> equalityComparer = EqualityComparer<T>.defaultComparer;
if (equalityComparer == null)
{
equalityComparer = EqualityComparer<T>.CreateComparer();
EqualityComparer<T>.defaultComparer = equalityComparer;
}
return equalityComparer;
}
}
private static EqualityComparer<T> CreateComparer()
{
RuntimeType genericParameter1 = (RuntimeType) typeof (T);
if ((Type) genericParameter1 == typeof (byte))
return (EqualityComparer<T>) new ByteEqualityComparer();
// Some ifs go on
else
return (EqualityComparer<T>) new ObjectEqualityComparer<T>();
}
这篇关于List.Contains是否与List.IndexOf完全相当?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!