目录

一、集合

1.IEnumerable和IEnumerator接口

(1)示例:通过自定义集合存储商品信息

2.List和IList 

(1)示例1

(2)示例2

二、索引器

1.索引器与属性的区别

2.示例:通过索引器访问元素


一、集合

        .NET提供了一种称为集合的数据类型,类似于数组,是一组组合在一起的类型化对象,可以通过遍历获取其中的每个元素。相对于数组,它的存储空间是动态变化的,可以对其中的数据进行添加、删除、修改等操作。

        集合需要使用System.Collections命名空间的集合接口来实现。该空间提供的常用的接口及说明:

1.IEnumerable和IEnumerator接口

        IEnumerable接口用于公开枚举数,该枚举数支持在非泛型集合上进行简单迭代(迭代就是循环遍历,重复执行同一过程)。IEnumerable接口有一个GetEnumerator()方法,用来返回循环访问集合的枚举器。迭代集合时使用。

IEnumerable接口定义:
public interface IEnumerable

GetEnumerator()方法定义:
IEnumerator GetEnumerator()

        在实现 IEnumerable接口的同时,还需要实现 IEnumerator接口。该接口支持对非泛型集合的简单迭代。它包括3个成员,分别是Current属性、MoveNext()方法和Reset()方法。

object Current{get}    //获取集合中当前位置元素
bool MoveNext()        //迭代集合中的下一个元素
void Reset()           //设置为初始位置,位于集合中第一个元素的前面

(1)示例:通过自定义集合存储商品信息

        继承 IEnumerable和IEnumerator接口并定义一个集合来存储商品信息,遍历输出集合中的商品信息。

// 集合
using System.Collections;

namespace _06
{
    public class Goods(string code, string name)        //定义集合中的元素类,表示商品信息类
    {
        public string Code = code;                      //编号
        public string Name = name;                      //名称
    }
    public class JHClass : IEnumerable, IEnumerator     //定义集合类
    {
        private readonly Goods[] _goods;                //初始化Goods类型的集合
        public JHClass(Goods[] gArray)                  //使用带参构造函数赋值
        {
            _goods = new Goods[gArray.Length];
            for (int i = 0; i < gArray.Length; i++)
            {
                _goods[i] = gArray[i];
            }
        }
        
        IEnumerator IEnumerable.GetEnumerator() //实现IEnumerable接口中GetEnumerator方法
        {
            return (IEnumerator)this;
        }
        int position = -1;                      //记录索引位置
        object IEnumerator.Current              //实现IEnumerator接口中的Current属性
        {
            get
            {
                return _goods[position];
            }
        }
        public bool MoveNext()                  //实现IEnumerator接口中的MoveNext方法
        {
            position++;
            return (position < _goods.Length);
        }
        public void Reset()                     //实现IEnumerator接口中的Reset方法
        {
            position = -1;                      //指向第一个元素
        }
    }
    class Program
    {
        static void Main()
        {
            Goods[] goodsArray =
            [
                new("T0001", "HuaWei MateBook"),
                new("T0002", "荣耀V30 5G"),
                new("T0003", "华为平板电脑"),
            ];                                   //初始化Goods类型的集合
            JHClass jhList = new(goodsArray);    //使用数组创建集合类对象
            foreach (Goods g in jhList)          //遍历集合,此处Goods类不是集合Goods[]
                Console.WriteLine(g.Code + " " + g.Name);
            Console.ReadLine();
        }
    }
}
//运行结果:
/*
T0001 HuaWei MateBook
T0002 荣耀V30 5G
T0003 华为平板电脑    */

2.List和IList 

         List和IList之间的主要区别在于List是一个具体的类,它表示可以由索引访问的对象的列表;而IList是一个接口,它表示可以由索引访问的对象的集合。IList接口由两个接口实现,它们是ICollection和IEnumerable。

(1)示例1

// IList接口及与List的比较
namespace _IList
{
    class IList_Program
    {
        static void Main(string[] args)
        {
            IList<string> ilist =   
            [
                "Mark",
                "John"
            ];                          //IList可以由索引访问的对象的集合
            List<string> list = [];     //List可以由索引访问的对象的列表
            list.Add("Mark");
            list.Add("John");

            foreach (string lst in list)
            {
                Console.WriteLine(lst);
            }
            Console.WriteLine();
            Console.WriteLine("---对比---");
            Console.WriteLine();
            foreach (string lst in ilist)
            {
                Console.WriteLine(lst);
            }
            Console.ReadLine();
        }
    }
}
//运行结果:
/*
Mark
John

---对比---

Mark
John    */

(2)示例2

IList Interface (System.Collections) | Microsoft Learn  

https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.ilist?view=net-8.0

二、索引器

        C#支持一种名为索引器的特殊“属性”,索引器允许一个对象可以像数组一样被索引。索引器的声明方式与属性相似。

1.索引器与属性的区别

  •  索引器在声明时需要使用this关键字定义参数,而属性不需要。
  •  索引器的名称必须是关键字this,this之后一对[],在[]之间指定索引的参数列表,其中必须至少有一个参数。
  • 索引器不能被定义为静态的,定义时不能使用static关键字。可用的修饰符有new、public、protected、internal、private、virtual、sealed、override、abstract、extern。
  • 索引器的使用方式不同于属性的使用方式,需要使用元素访问运算符[],并在其中指定参数进行引用。
  • 当索引器声明包含extern修饰符时,称为外部索引器,由于外部索引器声明不提供任何实现,所以它的每个索引器声明都由一个分号组成。
[修饰符][类型]this[参数列表]
{
    get{get访问器体}
    set{set访问器体}
}

2.示例:通过索引器访问元素

         定义一个类,在类中声明索引器,在Main()方法中创建类的对象,通过索引器为数组元素赋值,遍历数组元素。

// 通过索引器访问类元素
namespace _07
{
    /// <summary>
    /// 创建类并在其中声明索引器
    /// </summary>
    class CollClass
    {
        public const int SIZE = 4;         //表示数组的长度
        private readonly string[] arrStr;  //声明数组
        public CollClass()                 //构造方法
        {
            arrStr = new string[SIZE];     //设置数组的长度
        }
        public string this[int index]      //定义索引器
        {
            get
            {
                return arrStr[index];      //通过索引器取数组元素值
            }
            set
            {
                arrStr[index] = value;     //通过索引器给数组元素赋值
            }
        }
    }

    class Program
    {
        /// <summary>
        /// 通过索引器访问类中的元素
        /// </summary>
        static void Main(string[] args)
        {
            CollClass cc = new();    //创建CollClass类的对象=数组
            cc[0] = "CSharp";        //通过索引器给数组元素赋值
            cc[1] = "ASP.NET";       //通过索引器给数组元素赋值
            cc[2] = "Python";        //通过索引器给数组元素赋值
            cc[3] = "Java";          //通过索引器给数组元素赋值
            for (int i = 0; i < CollClass.SIZE; i++)          //遍历所有的元素
            {
                Console.WriteLine("cc[{0}] = {1}", i, cc[i]); //通过索引器取值
            }
            Console.Read();
        }
    }
}
//运行结果:
/*
cc[0] = CSharp
cc[1] = ASP.NET
cc[2] = Python
cc[3] = Java        */

        其它常用接口的用法及示例待作者完成创作和测试后逐渐发布。

11-22 20:56