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

C# 3.0 .NET 中的类型和集合

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.20/5 (5投票s)

2010 年 7 月 13 日

CPOL

5分钟阅读

viewsIcon

46833

定义集合和类型,并解释它们在 C# 3.0 语言中的用途。

摘要

集合和类型是确保开发人员代码强类型化的安全方式。强类型化的代码无需进行类型转换操作,可以在编译时捕获错误,而不是在运行时出现错误。在 .NET 程序集中使用集合和类型可以减少转换输入所需的时间和内存。集合还具有易于枚举的优点,并且像项目数量和集合迭代器这样的属性可以简化实现。Anupam Banerji 解释了它们的用法。

引言

.NET 开发人员经常需要转换数据类型。来自文本框控件或控制台输入的字符串可能需要转换为整数、双精度浮点数或布尔值类型。然后,该类型可以用于对象集合中。通常需要创建自定义引用类型来存储对象的各种属性。为了进行排序或存储,可能需要大量这些对象。类型和集合提供了高效的实现技术。

Types

类型是存储在内存中的一段数据。有两种类型。值类型是内置的 .NET 数据类型。例如,整数、双精度浮点数、十进制数、单精度浮点数、布尔值、字符、日期/时间以及字节都是 .NET 数据类型。值类型存储在称为堆栈的区域中,这是一个从 DOS 时代沿袭下来的后进先出 (LIFO) 存储空间。堆栈的访问速度很快,并且存储的类型是索引化的。引用类型是用户定义的类型(.NET 提供了许多预构建的引用类型),存储在称为堆的内存区域中。对象、字符串、数组和流是 .NET 提供的引用类型。所有类型(值类型和引用类型)都派生自 object 类型,即 .NET 公共类型系统 (CTS) 中最简单的数据类型。

用户定义的类型可以同时包含 CTS 值类型和引用类型。一个简单的用户定义类型是枚举。

private enum ExampleEnum
{ 
    firstItem, 
    secondItem 
} 

上面的枚举提供了一个基于整数的索引,允许开发人员为整数索引分配名称。使用枚举可以使实现更轻松、更安全。

最简单的用户定义类型是结构。

struct ExampleStr 
{     
    public string str; 
    public object o; 
    public Exception e; 
} 

然后通过声明该类型的变量来使用结构。

ExampleStr ex = new ExampleStr(); 

容纳数据的第三种方式是类类型。类是包含类型和其他代码的对象,是面向对象设计模式的关键构建块。类是引用类型;它们的实例化方式与结构相同,并且具有构造函数。类与结构不同之处在于它们可以派生基类、实现接口,并且在 .NET 中,可以通过实现的垃圾回收来控制它们的处置。

集合

集合是类型的组合。存在多种类型的集合。例如,ArrayList、Queue、Stack、StringCollection 和 BitArray。还有泛型集合,如 SortedList<T,U>、Queue<T>、Stack<T> 和 List<T>。当底层数据类型实现 IComparable 接口时,可以通过实现的接口方法对泛型集合进行排序。

类型转换操作

为什么需要类型和集合?在需要时,可以将对象转换为 CTS 类型,然后再转换回有用的类型。存在一些原因说明为什么应该避免实例化常用类型并将其转换回所需类型。

第一个原因是将 CTS 类型转换为另一种类型所需的时间。当值类型被转换为 object 类型时,会发生装箱操作。当 object 类型被转换为值类型时,会发生拆箱操作。装箱和拆箱操作会导致性能损失。如果代码中有数千次此类操作,那么性能会有明显下降。

还有另一个问题。不正确的装箱或拆箱对象会在运行时引发无效的类型转换异常。在设计时正确声明方法的输入会在编译时(而不是运行时)产生错误。

快速示例

现在我们将构建一个简单的可排序类和一个泛型集合来演示本文介绍的一些概念。我们创建一个实现 IComparable 接口的类。该类实现了 CompareTo() 接口方法。

using System.Collections;
using System.Collections.Generic;

public class Sortable : IComparable 
{
    private string name
    {
        get;
        private set;
    }

    private int price
    {
        get;
        private set;
    }
    public Sortable()
    {
    }

    public void Add(string _name, int _index)
    {
        name = _name;
        price = _index;
    }

    #region IComparable Members

    int IComparable.CompareTo(object obj)
    {
        return price.CompareTo(((Sortable)obj).price); 
    }

    #endregion
}

该类添加一个带有名称和索引的项。接口实现比较价格,并返回一个整数:如果价格相同,则值为零;如果价格低于比较价格,则小于零;如果价格高于比较价格,则大于零。必须先将要比较的对象拆箱为 Sortable 类,然后才能比较价格。这是可以预期的;实现的接口无法处理自定义对象。

现在创建主函数。项目集合存储在 List<T> 对象中。

List<Sortable> list = new List<Sortable>(); 

然后我们将项添加到泛型列表集合中。一旦填充了该集合,我们就可以对列表进行排序。

list.Sort(); 

或者反转排序顺序。

list.Reverse(); 

排序函数使用 Sortable 类中实现的 IComparable 接口来比较排序值。我们可以轻松地按名称属性进行排序。

#region IComparable Members

int IComparable.CompareTo(object obj)
{
    return name.CompareTo(((Sortable)obj).name); 
}

#endregion

List<T> 集合包含 ArrayList 对象的多个泛型方法。我们还可以将 Stack<T> 泛型映射到 Stack 对象,将 Queue<T> 集合映射到 Queue 对象。Stack 和 Queue 不进行排序。Stack 是后进先出 (LIFO) 模型,而 Queue 是先进先出 (FIFO) 模型。Stack 将使用 Push() 和 Pop() 方法来添加和删除项,而 Queue 将使用 Enqueue() 和 Dequeue() 方法来添加和删除项。

结论

类型和集合是处理大量数据的一种强大、安全且有效的方式。实现类型安全的 C# 代码可以减少运行时错误,并允许开发人员重用预构建的 .NET 接口和方法。实现错误更少,代码算法也更容易理解。因此,建议将使用类型和集合作为标准的开发实践。

本文的 PDF 版本可从 Coactum Solutions 网站下载,网址为 http://www.coactumsolutions.com

© . All rights reserved.