c# - List.Contains 是否完全等同于 List.IndexOf?

标签 c# .net list generics

List.Contains() 的 MSDN 描述说

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).

List.IndexOf()的描述说

This method determines equality using the default equality comparer EqualityComparer.Default for T, the type of values in the list.

EqualityComparer.Default描述说

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.

这有点可疑 - Contains 的描述只提到了 IEquatable 并且可以将没有实现 IEquatable 的内容放入 列表

所以我猜他们只是使用了相同的语义,也许 Contains() 重用了 IndexOf()

那么它们在比较方面是否完全等效?

最佳答案

简答:

  • 不,Contains()不重复使用 IndexOf()
  • 是的,它们在比较方面是等价的

我反编译 (ReSharper) 并看到最终两者都使用 abstract EqualityComparer<T>.Default.Equals(T x, T y)方法。 Default EqualityComparer<T> 的实例根据类型 T 进行初始化(和缓存)。

列表.包含

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;
}

这就是 EqualityComparer.Default 的实例化

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>();
}

关于c# - List.Contains 是否完全等同于 List.IndexOf?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23133470/

相关文章:

c# - 在测试期间提高 Entity Framework 性能

list - 如何将 CMake 列表作为集合进行操作?

c# - 无法在 Xamarin 中设置 SwitchCell 的绑定(bind)

c# - 具有 2 种单元格类型的 WP 7 列表框

c# - 异常 :The total length of a DataValidation list cannot exceed 255 characters

c# - 相交 LINQ 查询

c# - 我需要在页面加载后发帖,但我使用的是 Thread

c# - 如何验证 XPS 文档?

python - 从列表中删除\r

C:按给定排序对结构列表进行排序