独上高楼网站
  •    你所在位置:首页 VS.netC#C#高级编程(4版)〉泛型—集合接口
  • 泛型—集合接口
  • 作者:abatei  文章来源:博客园  发布日期:2008-02-21  浏览次数:375
  • 打印这篇文章
  • .NET Framework为集合的枚举和对比提供了两组标准接口:传统的(非类型安全)和新的泛型类型安全集合。本书只聚焦于新的,类型安全的集合接口,因为它更优越。

    您可以声明一些指定了类型的ICollection来取代实际类型(如intstring),以用于接口声明中的泛型类型(< T>)。

    C++程序员需要注意:C#泛型和C++中的模板在语法和用法上都很相似。但是,因为泛型在运行期为其指定类型进行扩展,JIT编译器可以为它们的不同的实例共享一段代码,从而使得在使用C++模板时有可能出现的代码膨胀问题在这里显著地减少。

    关键的泛型集合接口列于表9-2

    For backward compatibility, C# also provides nongeneric interfaces (e.g., ICollection, IEnumerator), but they aren't considered here because they are obsolescent.

    为了向后兼容,C#也提供了非泛型接口(如IConnectionIEnumerator),但由于慢慢被弃用,这里并不列出他们。

    9-2 集合接口

    接口

    用途

    ICollection< T>

    泛型集合的基接口

    IEnumerator< T>

    IEnumerable< T>

    使用foreach语句枚举整个集合

    ICollection< T>

    被所有集合实现以提供CopyTo()方法,Count,IsSynchronized和SyncRoot属性

    IComparer< T>

    IComparable< T>

    对比集合中的两个对象,使得集合可以被排序

    IList< T>

    象数组一样使用索引访问集合

    IDictionary< K,V>

    在基于键/值的集合中使用,如Dictionary

    9.4.1 IEnumerable< T>接口

    您可以通过实现IEnumerable< T>接口来使得ListBoxTest支持foreach语句(见例9-11)。IEnumerable只有一个方法:GetEnumerator(),它的工作是返回一个实现了IEnumerator< T>接口的类。C#语言使用一个新的关键字yield来为创建枚举器(enumerator)提供特殊的帮助。

    9-11 创建ListBox的可枚举类

    using System;
    using System.Collections; //译者注:这句原文没有,必须添加
    using System.Collections.Generic;
    using System.Text;

    namespace Enumerable
    {
        
    public class ListBoxTest : IEnumerable< string>
        {
            
    private string[] strings;
            
    private int ctr = 0;
            
    //Enumerable类可以返回一个枚举器
            public IEnumerator< string> GetEnumerator()
            {
                
    foreach (string s in strings)
                    
    yield return s;
            }
            
    /*译者注:泛型IEnumerable的定义为
             *public interface IEnumerable< T> : IEnumerable
             * 也就是说,在实现泛型版IEnumerable的同时还必须同时实现
             * 非泛型版的IEnumerable接口,原文代码并没有这个内容,下面的三行
             * 代码是我添加进去的以使得代码可以直接拷贝并运行
    */
            IEnumerator IEnumerable.GetEnumerator()
            {
                
    return GetEnumerator();
            }
            
    //使用字符串数组来初始化ListBox
            public ListBoxTest(params string[] initialStrings)

            {
                
    //为strings分配空间
                strings = new string[8];
                
    //拷贝从构造方法传递进来的字符串数组
                foreach (string s in initialStrings)
                {
                    strings[ctr
    ++= s;
                }
            }
            
    //在ListBox未尾添加一个字符串
            public void Add(string theString)
            {
                strings[ctr] 
    = theString;
                ctr
    ++;
            }
            
    //允许象数组一样访问,其实就是索引器,如果对索引器有不明白的请访问:
            
    //http://www.enet.com.cn/eschool/video/c/20.shtml
            public string this[int index]
            {
                
    get
                {
                    
    if (index <  0 || index >= strings.Length)
                    {
                        
    //处理错误的索引
                        
    //译者注:原文这里没加代码,我加了一个异常下去
                        throw new ArgumentOutOfRangeException("索引""索引超出范围");
                    }
                    
    return strings[index];
                }
                
    set
                {
                    strings[index] 
    = value;
                }
            }
            
    //获得拥有字符串的数量
            public int GetNumEneries()
            {
                
    return ctr;
            }
        }
        
    public class Tester
        {
            
    static void Main()
            {
                
    //创建一个新的ListBox并初始化
                ListBoxTest lbt = new ListBoxTest("Hello""World");
                
    //添加一些字符串
                lbt.Add("Who");
                lbt.Add(
    "Is");
                lbt.Add(
    "John");
                lbt.Add(
    "Galt");
                
    //访问测试
                string subst = "Universe";
                lbt[
    1= subst;
                
    //列出所有字符串
                foreach (string s in lbt)
                {
                    Console.WriteLine(
    "Value: {0}", s);
                }
            }
        }
    }
     

    输出结果:

    Value: Hello

    Value: Universe

    Value: Who

    Value: Is

    Value: John

    Value: Galt

    Value:

    Value:

    程序从Main()开始执行,创建一个新的ListBoxTest对象并给构造方法传递了两个字符串。当对象被创建后,将创建一个容纳8个元素的数组。如上例所示,之后使用Add方法添加了4个字符串,并更改了第二个字符串。

    这个版本的程序的一个重大变化是调用了foreach循环来获得listbox中的每个字符串。Foreach循环自动使用IEnumerable< T>接口并调用GetEnumerator()

    GetEnumerator方法声明为返回一个字符串类型的IEnumerator

    public IEnumerator< string> GetEnumerator()

    迭代的实现是遍历整个字符串并依次访问每个元素:

    foreach (string s in strings)

    {       

    yield return s;

    }

  • 打印这篇文章
  • 与本文主题相关的文章
  • 返回首页