关于数据集合的处理,前面已经讨论过数组的使用,主要使用了Array类,使用Array对象时,首先会确定成员数量,需要改变成员数量时,就会创建一个新的Array对象,这样一来,动态处理数组的效率是比较低的;不过,在.NET Framework类库中还提供了不少用于处理集合的资源,它们主要定义在两个命名空间,即:

  • System.Collections命名空间,定义集合处理的非泛型类型。
  • System.Collections.Generic命名空间,定义集合处理的泛型类型。

接下来将介绍两组集合处理的类型,分别是ArrayList类和List泛型类,Hashtable类和Dictionary泛型类,请注意它们定义的命名空间,并在代码文件中正确引用。

ArrayList类与List泛型类

ArrayList类和List泛型类用于处理有序的集合,成员使用从0开始的索引值进行访问。下面的代码,我们先来看ArrayList类的基本应用。

static void Main(string[] args)
{
        ArrayList arr = new ArrayList();
        arr.Add("aaa");
        arr.Add(123);
        arr.Add(true);
        arr.Insert(0, DateTime.Now);
        //
        foreach(object obj in arr)
        {
            Console.WriteLine(obj.ToString());
        }
}

本例中,首先定义了ArrayList类型的arr对象,使用Add()方法添加了三个成员,然后使用Insert()方法将系统的当前时间添加到索引值为0的位置(即第一个成员);最后,使用foreach语句显示所有的成员。代码执行结果如下图所示(你的执行结果应该只有第一个成员的时间不一样)。

enter image description here

这里,我们可以看到ArrayList类的一些特点,最主要的是其成员类型是Object类型的,也就是说,可以将任何类型添加到ArrayList对象的成员中,这样可以有最大的灵活性,但问题也同样突出,即在集合中同时处理多种数据类型时,类型的转换是需要时间的,这就给代码的执行效率带来了负面影响;而List泛型类就可以解决部分问题,当集合成员的数据类型相同时,就可以使用List类来提高代码的执行效率,如下面的代码。

static void Main(string[] args)
{
        List<string> lst = new List<string>();
        lst.Add("aaa");
        lst.Add("bbb");
        lst.Add("ccc");
        //
        for (int i = 0; i < lst.Count; i++)
        {
            Console.WriteLine(lst[i]);
        }
}

代码执行结果如下图所示。

enter image description here

实际应用中,ArrayList和List类有很多相似之处,包括相同的成员名,如Add()、Insert()、Remove()等方法,Count等属性,以及从0开始的索引值等等。只是需要注意一点,ArrayList对象的成员类型是Object,灵活保存各种类型的数据时,有时会需要类型转换工作,而List对象中的成员类型是相同的,这样就可以更直接地处理(效率更高);区分它们之间的不同,才可以在代码中合理地选择应用。

Hashtable类和Dictionary泛型类

Hashtable类和Dictionary泛型类,用于处理“键/值”对应的数据类型,即在集合中,每一个键(Key)对应一个值(Value),可以使用键来访问相应的数据值。下面是Hashtable类的基本应用方式。

static void Main(string[] args)
{
        Hashtable hash = new Hashtable();
        hash.Add("Earth", "地球");
        hash.Add("Mars", "火星");
        Console.WriteLine(hash["Mars"]);
}

这里,使用hash["Mars"]访问hash对象中键为Mars的数据,代码会显示“火星”。

Hashtable的键、值都定义为Object类型,这样也就带来了最大的灵活性,和ArrayList的问题一样,当使用不同类型的数据时,可能需要类型的转换工作;而Dictionary泛型类则可以绑定键和值的类型,如下面的代码。

static void Main(string[] args)
{
        Dictionary<string, string> dict = new Dictionary<string, string>();
        dict.Add("Earth", "地球");
        dict.Add("Mars", "火星");
        Console.WriteLine(dict["Mars"]);
}

代码执行同样会显示“火星”。

使用Hashtable和Dictionary类时还应该注意,键的内容是区分大小写的,即mars和Mars表示不同的数据项,如果使用了不存在的键,则返回一个空值。另一方面,在使用这两个类时,不应假设成员的顺序,而只是使用指定的键来返回数据值,需要访问所有成员时,可以使用foreach语句结构遍历所有的键进行操作,如下面的代码。

    static void Main(string[] args)
    {
        Dictionary<string, string> dict = new Dictionary<string, string>();
        dict.Add("Earth", "地球");
        dict.Add("Mars", "火星");
        //
        foreach(string k in dict.Keys)
        {
            Console.WriteLine("{0} : {1}", k, dict[k]);
        }
    }

本例中,Dictionary对象的Keys属性返回了所有键的集合,并通过foreach语句结构遍历所有键显示相应的数据值,代码执行结果如下图所示。

enter image description here

以上,我们了解了常用的集合类型,包含使用从0开始索引的“有序”集合ArrayList类和List泛型类,以及使用键索引的“无序”集合Hashtable类和Dictionary泛型类;大家可以根据这些集合类的特点合理应用到自己的代码中。

综合应用

实际应用中,可以根据实际需要扩展集合类的使用,如下面的代码。

using System.Collections.Generic;

namespace ConsoleTest
{
    //
    public class CDataItem
    {
        //
        public CDataItem(string sName, object oValue)
        {
            Name = sName;
            Value = oValue;
        }
        //
        public string Name { get; set; }
        public object Value { get; set; }
    }
    //
    public class CDataList : List<CDataItem>
    {

    }
}

本例,首先定义了CDataItem类,其中包含两个属性,分别是Name属性(string类型)和Value属性(object类型);然后,定义了CDataList类,其继承于List类型,也就是说,列表的成员类型是CDataItem对象;接下来,CDataList类型包含了列表基本操作,并可以根据需要创建自己的操作方法。这里定义的CDataList类,即可以保持成员的有序性,也可以根据数据的名称进行相应的操作,如下面的代码,我们可以在CDataList类中定义一个Find()方法,用于查询指定名称的数据项,并返回其索引值,没有找到时返回-1。

public class CDataList : List<CDataItem>
{
    public int Find(string sName)
    {
        for(int i=0;i<Count;i++)
        {
            if (string.Compare(sName, this[i].Name, false) == 0)
                return i;
        }
        return -1;
    }
}

下面的代码演示了Find()方法的使用。

static void Main(string[] args)
{
        CDataList lst = new CDataList();
        lst.Add(new CDataItem("Earth", "地球"));
        lst.Add(new CDataItem("Mars", "火星"));
        //
        Console.WriteLine(lst.Find("Mars"));
        Console.WriteLine(lst.Find("Moon"));
}

代码执行结果如下图所示。

enter image description here

CHY软件小屋原创作品!