C#_创建自己的MyList列表

发布于:2025-07-31 ⋅ 阅读:(28) ⋅ 点赞:(0)

定义一个数据自己的列表MyList  使用上述描述列表的方式(数组)  列表内也要定义属于自己的方法  例如 Sort排序 Add添加 等等....

思路

┌─────────────────────────────────────────────────────────────────┐
│                    开始:实现 MyList<T> 泛型类                    │
└───────────────────────────────────┬─────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────┐
│                1. 定义核心成员(存储与计数)                       │
│  ┌───────────────┐    ┌───────────────┐                         │
│  │  private T[] data  │    │  private int count  │              │
│  │  (内部存储数组)  │    │  (实际元素数量)   │                  │
│  └───────────────┘    └───────────────┘                         │
└───────────────────────────────────┬─────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────┐
│                2. 实现基础属性(对外暴露信息)                    │
│  ┌────────────────────────┐  ┌────────────────────────┐         │
│  │  public int Capacity   │  │  public int Count      │         │
│  │  (获取数组容量)      │  │  (获取元素总数)      │         │
│  │  get { return data.Length; }  get { return count; }  │         │
│  └────────────────────────┘  └────────────────────────┘         │
└───────────────────────────────────┬─────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────┐
│                3. 实现核心功能方法                                │
├───────────────┬───────────────┬───────────────┬───────────────┐   │
│   Add(T item) │ Insert(...)   │ RemoveAt(...) │  IndexOf(...) │   │
│  (添加元素) │ (插入元素)  │ (删除元素)  │ (查找索引)  │   │
├───────────────┼───────────────┼───────────────┼───────────────┤   │
│  LastIndexOf(...)  │   Sort()    │  索引器 [...]  │  KR()扩容   │   │
│  (反向查索引)    │ (排序)    │ (元素访问)  │ (内部用)  │   │
└───────────────┴───────────────┴───────────────┴───────────────┘   │
└───────────────────────────────────┬─────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────┐
│                4. 支持高级特性(遍历与初始化)                    │
│  ┌─────────────────────────────────┐  ┌─────────────────────┐   │
│  │  实现 IEnumerable<T> 接口        │  │  添加构造函数       │   │
│  │  - GetEnumerator()              │  │  - 接收 IEnumerable │   │
│  │  - 用 yield return 遍历元素      │  │  - 批量添加元素     │   │
│  └─────────────────────────────────┘  └─────────────────────┘   │
└───────────────────────────────────┬─────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────┐
│                5. 测试验证                                      │
│  - 集合初始化器:new MyList<int> {1,2,3}                       │
│  - foreach 遍历元素                                             │
│  - 增/删/查/改/排序功能验证                                      │
└───────────────────────────────────┬─────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────┐
│                    结束:功能完成                                │
└─────────────────────────────────────────────────────────────────┘

首先定义一个 MyList<> 泛型类

 internal class MyList<T> : IEnumerable<T>
 {
     private T[] data = new T[0];
     private int count = 0;//数据个数

     public int Capacity //获取或设置列表的容量
     {
         get { return data.Length; }
     }

     public void Add(T item)
     {
         KR();
         data[count] = item;
         count++;
     }//添加数据

     public int Count //Count数据个数,不能set设置count值,放止外界修改
     {
         get
         {
             return count;
         }
     }

     // 集合初始化器构造函数
     public MyList(IEnumerable<T> collection)//collection代表集合 {}
     {
         foreach (var item in collection)
         {
             Add(item);
         }
     }
     // 无参构造函数
     public MyList() { }

     #region 插入数据的方法 Insert
     public void Insert(int index, T item)
     {
         if (index < 0 || index > count - 1)
         {
             throw new IndexOutOfRangeException("索引参数超出范围了");
         }
         KR();

         for (int i = count - 1; i > index - 1; i--)
         {
             data[i + 1] = data[i];

         }
         data[index] = item;
         count++;

     }
     #endregion

     #region 扩容
     private void KR()
     {
         if (data.Length == 0)
         {
             data = new T[4];
         }
         //添加元素前,判断数组是否满
         if (data.Length == count)
         {
             T[] temp = new T[count * 2];
             for (int i = 0; i < data.Length; i++)
             {
                 temp[i] = data[i];
             }
             data = temp;
         }
     }
     #endregion

     #region 索引器 [index]
     //dx通过索引器访问方法
     public T this[int index]
     {
         get
         {
             if (index < 0 || index > count - 1)
             {
                 throw new IndexOutOfRangeException("索引参数超出范围了");
             }
             return data[index];
         }
         set
         {
             data[index] = value;
         }
     }

     #endregion 

     #region 整数类型排序 Sort
     public void Sort()
     {
         bool isChange ;//标记排序是否完成
         int num = 0; //记录交换次数
         for (int i = 0; i < count - 1; i++)
         {
             isChange = false; // 每次外层循环开始时重置为false
             for (int j = 0; j < count - 1-i; j++)
             {
                 if ((dynamic)data[j] > (dynamic)data[j + 1])
                 {
                     T temp = data[j];
                     data[j] = data[j + 1];
                     data[j + 1] = temp;
                     isChange = true;
                     num++;
                 }
             }
             if (isChange == false)
             { break; }
         }
         Console.WriteLine($"交换了:{num}次");
     }
     #endregion

     #region 索引删除数据 RemoveAt
     public void RemoveAt(int index)
     {
         if (index < 0 || index > count - 1)
         {
             throw new IndexOutOfRangeException("索引参数超出范围了");
         }

         for (int i = index; i < count-1; i++)
         {
             data[i] = data[i + 1];            
         }
         count--;
     }
     #endregion

     #region 取得第一个对应元素所在列表中的索引位置 IndexOf
     public int IndexOf(T item)
     {
         int index=-1;//定义一个索引值

         for (int i = 0; i < count; i++)
         {
             if (item.Equals(data[i]))
             {
                index=i;break;
             }
         }

         if (index == -1)
         {
             Console.WriteLine("没有要查找的数据");
         }
         return index;
     }
     #endregion

     #region 取得最后一个对应元素所在列表中的索引位置 LastIndexOf
     public int LastIndexOf(T item)
     {
         int index = -1;//定义一个索引值

         for (int i = count-1; i >= 0; i--)
         {
             if (item.Equals(data[i]))
             {
                 index = i; break;
             }
         }

         if (index == -1)
         {
             Console.WriteLine("没有要查找的数据");
         }
         return index;
     }
     #endregion

     #region 实现IEnumerable<T>接口,支持foreach遍历
     public IEnumerator<T> GetEnumerator()
     {
         for (int i = 0; i < count; i++)
         {
             yield return data[i];
         }
     }

     IEnumerator IEnumerable.GetEnumerator()
     {
         return GetEnumerator();
     }
     #endregion
 }

主函数测试

  static void Main(string[] args)
  {
      MyList <int> list= new MyList<int>() { 1,5,6,88};
     
      list.Add(1);
      list.Add(5);
      list.Add(3);
      list.Add(4);
      list.Add(9);
      list.Add(6);
      list.Insert(0, 9);//在索引为0的位置添加一个数据

      Console.WriteLine("取得第一个对应元素所在列表中的索引位置"+list.IndexOf(9));
      Console.WriteLine("取得最后一个对应元素所在列表中的索引位置" + list.LastIndexOf(9));
      //删除索引位置在1的数据
      list.RemoveAt(1);
      //从小到大排序
      list.Sort ();

      Console.Write("列表数据包含:");
      foreach (int item in list)
      {
          Console.Write(item + " ");
      }
      Console.WriteLine("元素个数:" + list.Count);
  }

注:IEnumerable<T>

IEnumerable<T> 是 C# 中定义在 System.Collections.Generic 命名空间下的泛型接口,用于表示一个可枚举的集合。它是 .NET 集合框架中非常基础且重要的接口,所有支持 foreach 循环遍历 的集合都实现了这个接口(或其非泛型版本 IEnumerable)。

核心作用

  • 提供 统一的遍历方式:无论集合内部结构如何(数组、链表、哈希表等),只要实现了 IEnumerable<T>,就能通过 foreach 循环遍历元素。
  • 支持 延迟执行:配合 LINQ 时,可以实现查询的延迟执行(只在真正需要结果时才计算),提高性能。

接口定义

IEnumerable<T> 接口非常简单,只包含一个方法:

public interface IEnumerable<out T> : IEnumerable
{
    // 返回一个用于遍历集合的枚举器
    IEnumerator<T> GetEnumerator();
}

其中:

  • IEnumerator<T> 是另一个接口,负责实际遍历逻辑,包含 MoveNext()(移动到下一个元素)、Current(获取当前元素)等成员。
  • foreach 循环的本质就是调用 GetEnumerator() 获取枚举器,然后通过枚举器遍历元素。

例如,在 本代码中添加以下实现:

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

public class MyList<T> : IEnumerable<T>
{
    // 其他现有代码...

    // 实现 IEnumerable<T> 接口
    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < count; i++)
        {
            yield return data[i]; // 逐个返回元素,支持 foreach 遍历
        }
    }

    // 非泛型版本的实现(接口继承要求)
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到