C#中的List(T)类型代表T类的列表,该类型位于 System.Collections.Generic命名空间,提供了按位置索引获取对象的方法,并且列表支持搜索、排序等其它操作。本文重点介绍List(T)中的两个方法:Contains(T)和IndexOf(T),特别的,T为自定义类类型。
(1)List(T).Contains(T)方法
该方法用于检测某个T对象是否存在于List(T)对象中,List(T).Contains(T)方法继承自ICollection(T).Contains(T),并对其进行了实现。首先看.net中该方法对应的代码
// Contains returns true if the specified element is in the List. // It does a linear, O(n) search. Equality is determined by calling // item.Equals(). // public bool Contains(T item) { if ((Object) item == null) { for(int i=0; i<_size; i++) if ((Object) _items[i] == null) return true; return false; } else { EqualityComparer<T> c = EqualityComparer<T>.Default; for(int i=0; i<_size; i++) { if (c.Equals(_items[i], item)) return true; } return false; } }
通过该方法的实现代码可以看出:1,该方法支持待检测对象T为null,且当List(T)中含有null时,返回true,否则返回false;2,该方法使用EqualityComparer(T).Default比较器来比较两个对象的相等性。而对于自定义的类型T,若该类实现了IEquatable(T)接口(即实现了Equals(T item)方法),则EqualityComparer(T).Default比较器就是调用的该方法进行的相等性比较。而若是该类未实现该接口,则会引用C#中Object.Equals(object obj)方法进行相等性测试,而对于引用类型,只有在两个变量引用同一个实例(即实例在内存中的地址相等)时才会返回true。
(2)List(T).IndexOf(T)方法
该方法从List(T)中搜索特定的对象,并返回列表中第一个等于该对象的索引位置(以0为开始),当列表中不含有该对象时,返回-1。List(T).IndexOf(T)方法继承自IList(T).IndexOf(T),并对其进行了实现。首先看.net中该方法对应的代码:
// Returns the index of the first occurrence of a given value in a range of // this list. The list is searched forwards from beginning to end. // The elements of the list are compared to the given value using the // Object.Equals method. // // This method uses the Array.IndexOf method to perform the // search. // public int IndexOf(T item) { Contract.Ensures(Contract.Result<int>() >= -1); Contract.Ensures(Contract.Result<int>() < Count); return Array.IndexOf(_items, item, 0, _size); }
其中,所调用的Array类中IndexOf方法实现为:
public static int IndexOf<T>(T[] array, T value, int startIndex, int count) { if (array==null) { throw new ArgumentNullException("array"); } if (startIndex < 0 || startIndex > array.Length ) { throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); } if (count < 0 || count > array.Length - startIndex) { throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); } Contract.Ensures(Contract.Result<int>() < array.Length); Contract.EndContractBlock(); return EqualityComparer<T>.Default.IndexOf(array, value, startIndex, count); }
通过该方法的实现代码可以看出:1,该方法借助了Array类的Index()方法进行了功能实现;2,同样的,该方法使用EqualityComparer(T).Default比较器来比较两个对象的相等性。此规则与Contains(T)方法类似