65.9K
CodeProject 正在变化。 阅读更多。
Home

C# .NET 集合基础

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.46/5 (32投票s)

2008年12月10日

CPOL

6分钟阅读

viewsIcon

329716

downloadIcon

2642

本文重点介绍 .NET Framework 2.0 中的集合管理。

引言

本文重点介绍 .NET Framework 2.0 中的集合管理。集合代表一组可以通过逐个遍历元素来访问的对象。.NET Framework 提供了专门的类来管理集合,这些类具备丰富的强大功能,可提升编程体验,提高性能并简化维护。

Object 类是 .NET 中所有类型的基类。所有集合都实现了 IEnumerable 接口,该接口由 ICollection 接口扩展。IDictionaryIList 也是集合的接口,它们派生自 ICollection,如下图所示。

Class Giagram

System.Object

Object 类是所有类型的基类。所有其他类型都直接或间接继承自 object 类。鉴于其重要地位,.NET 开发者应充分了解 object 类及其成员。

  1. 静态方法

    • object.Equals(object objA, object objB) 

      此方法对 objAobjB 进行一些 null 测试,并调用 objA.Equals(objB)。如果 objAobjB 都是 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) 

      如果 objAobjB 是同一个实例,或者两者都为 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. 
  2. 方法

    • 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

它公开枚举器,为用户定义的类提供类似集合的行为。

  1. 方法

    • 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 命名空间中类的基接口。

  1. 属性

    • 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);
       }
  2. 方法

    • 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 允许添加、删除和修改元素。

  1. 属性

    • 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
  2. 方法

    • 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。此方法使用 EqualsCompareTo 方法来确定项是否存在。

       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 中特定项的索引。此方法也使用 EqualsCompareTo 方法来确定项是否存在。

       // 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 对象中。它允许枚举包含的键和值,但不暗示任何特定的排序顺序。

  1. 属性

    • 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
  2. 方法

    • Add(object key, object value) 

      将具有指定 keyvalue 的元素添加到 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

参考文献

历史

  • 2008年12月10日:初始帖子
© . All rights reserved.