C# .NET 集合基础






3.46/5 (32投票s)
本文重点介绍 .NET Framework 2.0 中的集合管理。

引言
本文重点介绍 .NET Framework 2.0 中的集合管理。集合代表一组可以通过逐个遍历元素来访问的对象。.NET Framework 提供了专门的类来管理集合,这些类具备丰富的强大功能,可提升编程体验,提高性能并简化维护。
Object
类是 .NET 中所有类型的基类。所有集合都实现了 IEnumerable
接口,该接口由 ICollection
接口扩展。IDictionary
和 IList
也是集合的接口,它们派生自 ICollection
,如下图所示。

System.Object
Object
类是所有类型的基类。所有其他类型都直接或间接继承自 object
类。鉴于其重要地位,.NET 开发者应充分了解 object
类及其成员。
-
静态方法
-
object.Equals(object objA, object objB)
此方法对
objA
和objB
进行一些null
测试,并调用objA.Equals(objB)
。如果objA
和objB
都是null
引用,或者两者都是同一个实例,或者objA.Equals(objB)
返回true
,则返回true
,否则返回false
。int n1 = 2; int n2 = 3; bool result1 = object.Equals(n1, n2); // returns false. // because n1 & n2 are value type // and it will be compared by value. string s1 = "test"; string s2 = "test"; bool result2 = object.Equals(s1, s2); // returns true. s1 & s2 are // reference type, // but Equals(object obj) method of // object class is overridden by // string class. // that's why it returns true because // s1 and s2 are comparing // by their values. object obj1 = new Person(1, "Test1"); object obj2 = new Person(1, "Test1"); bool result3 = object.Equals(obj1, obj2); // returns false. obj1 & obj2 // are reference type, // both are comparing by // reference and both are // different instances but // having same values.
-
object.ReferenceEquals(object objA, object objB)
如果
objA
与objB
是同一个实例,或者两者都为null
引用,则此方法返回true
,否则返回false
。int n1 = 2; int n2 = 2; bool result1 = object.ReferenceEquals(n1, n2); // returns false. // because n1 & n2 are // different instances. object obj1 = new Person(1, "Test1"); object obj2 = new Person(1, "Test1"); object obj3 = obj1; bool result2 = object.ReferenceEquals(obj1, obj2); // returns false because // obj1 & obj2 are different instances. bool result3 = object.ReferenceEquals(obj1, obj3); // returns true because // obj1 & obj2 are same instances.
-
-
方法
-
Equals(object obj)
Equals()
的默认实现仅支持引用相等性,但派生类可以重写此方法以支持值相等性。例如,string
类就重写了Equals()
,以确保两个字符串通过其值的相等性进行比较。在集合中进行搜索或排序等常见操作时,测试两个对象是否相等尤为重要。string s1 = "Test"; string s2 = "Test"; bool result1 = s1.Equals(s2); // returns true. // because s1 & s2 has same value. object obj1 = new Person(1, "Test1"); object obj2 = new Person(1, "Test1"); object obj3 = obj1; bool result2 = obj1.Equals(obj2); // returns false. // because obj1 & obj2 are different // instances. bool result3 = obj1.Equals(obj3); // returns true. // because obj1 & obj3 are same instances.
-
GetHashCode()
它返回当前对象的哈希码。此方法也作为特定类型的哈希函数。它适用于哈希算法和哈希表等数据结构。派生类可以重写此方法。
Object.GetHashCode()
为同一个实例返回相同的哈希码,但对于两个不同的实例,它不一定返回不同的哈希码,或者对于两个具有相同值的实例,它不一定返回相同的哈希码。不同版本的 .NET Framework 也可能为同一个实例生成不同的哈希码。GetHashCode()
方法返回的默认哈希码不能保证唯一,您应该在自定义类型中重写GetHashCode
。object obj1 = 4; object obj2 = "Test"; object obj3 = new Person(1, "Test1"); int result1 = obj1.GetHashCode(); // returns 4. int result2 = obj2.GetHashCode(); // returns -354185577. int result3 = obj3.GetHashCode(); // returns 2418355.
-
GetType()
它返回当前实例的
Type
对象。Type
是在 .NET 中使用反射的基础。使用Type
的成员可以获取有关类型声明的信息,例如类的构造函数、方法、字段、属性和事件,以及类部署所在的模块和程序集。object obj1 = 4; object obj2 = "Test"; object obj3 = new Person(1, "Test1"); string type1 = obj1.GetType().ToString(); // returns System.Int32 string type2 = obj2.GetType().ToString(); // returns System.String. string type3 = obj3.GetType().ToString(); // returns DotNetCollections. // CollectionExp.Person.
-
ToString()
它返回当前对象的、特定于区域性的、人类可读的字符串表示形式。默认实现返回对象的运行时类型。派生类可以重写此方法以返回有意义的类型值。例如,
Double
类的ToString()
方法返回对象所代表的值的字符串表示形式。object obj1 = 4; object obj2 = "Test"; object obj3 = new Person(1, "Test1"); string s1 = obj1.ToString(); // returns 4 string s2 = obj2.ToString(); // returns Test string s3 = obj3.ToString(); // returns DotNetCollections. // CollectionExp.Person.
-
System.Collections.IEnumerable
它公开枚举器,为用户定义的类提供类似集合的行为。
-
方法
-
GetEnumerator()
它返回可用于遍历集合的枚举器对象。它允许使用
foreach
语句。枚举器只允许读取集合中的数据。Array array = new int[] { 12, 24, 26, 35, 40, 59 }; IEnumerator iEnum = array.GetEnumerator(); string msg = ""; while (iEnum.MoveNext()) { int n = (int)iEnum.Current; msg += n.ToString() + "\n"; } MessageBox.Show(msg);
-
System.Collections.ICollection
ICollection
接口指定了一个用于获取集合大小、在集合上创建枚举器以及管理所有非泛型集合同步访问的方法。它是 System.Collections
命名空间中类的基接口。
-
属性
Count
它返回
ICollection
包含的元素数量。// Array List ArrayList sourceList = new ArrayList(); sourceList.Add(10); sourceList.Add(20); sourceList.Add(30); int count = sourceList.Count; // count = 3.
IsSynchronized
如果对
ICollection
的访问是同步的,则返回true
。SyncRoot
它返回一个可用于同步对
ICollection
访问的对象。ArrayList sourceList = new ArrayList(); sourceList.Add(10); sourceList.Add(20); sourceList.Add(30); lock (sourceList.SyncRoot) { string list = string.Empty; foreach (object value in sourceList) { if (list.Length > 0) list += ", "; list += value.ToString(); } MessageBox.Show(list); }
-
方法
-
CopyTo(Array array, int index)
CopyTo()
方法将ICollection
对象中的元素复制到任何数组中,从指定的Array
索引开始。如果 .NET 无法将源类型转换为目标类型,则会引发ArrayTypeMismatchException
异常。// Copy int array to other int array int[] sourceIDs = new int[] { 1, 2, 3, 4, 5 }; int[] destinationIDs = new int[sourceIDs.Length]; sourceIDs.CopyTo(destinationIDs, 0); // destinationIDs = 1, 2, 3, 4, 5 // Copy array list items to int array. // But each item in array list has int type ArrayList sourceList = new ArrayList(); sourceList.Add(10); sourceList.Add(20); sourceList.Add(30); int[] destinationList = new int[5]; destinationList[0] = 1; destinationList[1] = 5; sourceList.CopyTo(destinationList, 2); // start copy on index 2. // destinationList = 1, 5, 10, 20, 30
-
System.Collections.IList
IList
接口代表可通过索引单独访问的对象集合。IList
接口代表可通过索引单独访问的对象集合。IList
的实现分为三类:只读、固定大小和可变大小。只读 IList
不能被修改。固定大小的 IList
不允许添加或删除元素,但允许修改现有元素。可变大小的 IList
允许添加、删除和修改元素。
-
属性
IsFixedSize
如果
IList
是固定大小的,则返回true
。ArrayList arrayList = new ArrayList(); bool isFixedSize = arrayList.IsFixedSize; // false, because ArrayList // is not fixed size list
IsReadOnly
如果
IList
是只读的,则返回true
。ArrayList arrayList = new ArrayList(); arrayList.Add(1); arrayList.Add(2); arrayList.Add(3); bool readOnly = arrayList.IsReadOnly; // false, because default array // list is not readonly. // create readonly list from existing list ArrayList readOnlyList = ArrayList.ReadOnly(arrayList); bool isNewListReadOnly = readOnlyList.IsReadOnly; // true. now user can't // modify this list
-
方法
-
Add(object value)
它将项添加到
IList
中。ArrayList arrayList = new ArrayList(); arrayList.Add(1); // Add First Item arrayList.Add(2); // Add Second Item arrayList.Add(3); // Add Third Item
-
Clear()
它移除
IList
中的所有项。ArrayList arrayList = new ArrayList(); arrayList.Add(1); arrayList.Add(2); arrayList.Add(3); int itemsCount = arrayList.Count; // 3 arrayList.Clear(); itemsCount = arrayList.Count; // 0
-
Contains(object value)
如果
IList
包含特定值,则返回true
。此方法使用Equals
和CompareTo
方法来确定项是否存在。ArrayList arrayList = new ArrayList(); arrayList.Add(new Person(1,"test")); Person person1 = new Person(1, "test"); Person person2 = new Person(2, "test2"); bool result1 = arrayList.Contains(person1); // true bool result2 = arrayList.Contains(person2); // false
-
IndexOf(object value)
它返回
IList
中特定项的索引。此方法也使用Equals
和CompareTo
方法来确定项是否存在。// Populate Array list ArrayList arrayList = new ArrayList(); arrayList.Add(new Person(1, "test1")); arrayList.Add(new Person(2, "test2")); arrayList.Add(new Person(3, "test3")); // create new object Person person3 = new Person(3, "test3"); Person person4 = new Person(4, "test4"); int result1 = arrayList.IndexOf(person3); // 2, int result2 = arrayList.IndexOf(person4); // -1. because it does not exist // in list
-
Insert(int index, object value)
它将项插入到
IList
的指定索引处。如果索引等于IList
中的项数,则将值追加到末尾,但如果索引大于IList
中的项数或小于零,则会引发ArgumentOutOfRangeException
异常。如果您尝试在只读或固定大小的IList
中插入项,则会引发NotSupportedException
异常。ArrayList arrayList = new ArrayList(); arrayList.Add(new Person(1, "test1")); arrayList.Add(new Person(2, "test2")); arrayList.Add(new Person(3, "test3")); // create new object Person person =new Person(4, "test4"); // insert item at index 2. arrayList.Insert(2, person);
-
Remove(object value)
它从
IList
中移除特定对象的第一个匹配项。如果您尝试从只读或固定大小的IList
中移除值,则会引发NotSupportedException
。ArrayList arrayList = new ArrayList(); arrayList.Add(new Person(1, "test1")); arrayList.Add(new Person(2, "test2")); arrayList.Add(new Person(3, "test3")); // Create person Person person = new Person(2, "test2"); arrayList.Remove(person); // it will remove 2nd item. it will call // Equals method to object to find in list.
-
RemoveAt(int index)
它移除指定索引处的项。对于列表中无效的索引,会引发
ArgumentOutOfRangeException
异常;对于只读或固定大小的IList
,会引发NotSupportedException
异常。ArrayList arrayList = new ArrayList(); arrayList.Add(new Person(1, "test1")); arrayList.Add(new Person(2, "test2")); arrayList.Add(new Person(3, "test3")); arrayList.RemoveAt(1); // remove item at index 1
-
System.Collections.IDictionary
它代表键/值对的集合。IDictionary
接口由支持关联键和值集合的类实现。键/值对中的每个元素都存储在 DictionaryEntry
对象中。它允许枚举包含的键和值,但不暗示任何特定的排序顺序。
-
属性
IsFixedSize
如果
IDictionary
对象是固定大小的,则返回true
。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); bool result = hashList.IsFixedSize; // false
IsReadOnly
如果
IDictionary
对象是只读的,则返回true
。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); bool result = hashList.IsReadOnly;
密钥
它返回包含
IDictionary
对象键的ICollection
对象。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); ICollection keys = hashList.Keys; string[] strKeys = new string[keys.Count]; int index =0; foreach (int key in keys) { strKeys[index++] = key.ToString(); } string keysList = string.Join(", ",strKeys); // 3, 2, 1
值
它返回包含
IDictionary
对象值的ICollection
对象。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); ICollection values = hashList.Values; string[] strValues = new string[values.Count]; int index = 0; foreach (string value in values) { strValues[index++] = value; } string valueList = string.Join(", ", strValues); //item#1, item#2, item#3
-
方法
-
Add(object key, object value)
将具有指定
key
和value
的元素添加到IDictionary
对象中。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3");
-
Clear()
它移除
IDictionary
对象中的所有元素。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); hashList.Clear(); // it removes all item from the list.
-
Contains(object key)
如果
IDictionary
对象包含具有指定key
的元素,则返回true
。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); bool result = hashList.Contains(1); // true
-
GetEnumerator()
它返回
IDictionary
对象的IDictionaryEnumerator
对象。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); IDictionaryEnumerator dicEnum = hashList.GetEnumerator(); string items = string.Empty; while (dicEnum.MoveNext()) { items += string.Format("{0} : {1}\n", dicEnum.Key, dicEnum.Value); } MessageBox.Show(items);
-
Remove(object key)
它从
IDictionary
对象中移除具有指定key
的元素。Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); hashList.Remove(2); // remove item which has 2 key
-
参考文献
- http://msdn.microsoft.com/en-us/library/system.object(VS.71).aspx
- http://msdn.microsoft.com/en-us/library/system.collections.icollection.aspx
- http://msdn.microsoft.com/en-us/library/system.collections.ilist.aspx
- http://msdn.microsoft.com/en-us/library/system.collections.idictionary_members(VS.80).aspx
历史
- 2008年12月10日:初始帖子