• 泛型集合接口


     

    9.4 集合接口

    .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;

    }


  • 相关阅读:
    qmake杂
    Qt界面风格设置
    qss使用详解
    QT数据库操作
    Qt语言家的简单使用
    c++11之右值引用和std::move
    c++11之类型萃取type_traits
    c++11之std::bind和function
    c++11之lambda
    vue中input输入框无法输入
  • 原文地址:https://www.cnblogs.com/abatei/p/1065918.html
Copyright © 2020-2023  润新知