List.Contains是否与List.IndexOf完全相当? [英] Is List.Contains fully comparison-wise equivalent to List.IndexOf?

查看:146
本文介绍了List.Contains是否与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 reuse IndexOf()
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆