草庐IT

C# 自定义List

熊思宇 2023-11-13 原文

目录

一、需求

二、List 常用功能

三、自定义List

四、测试

1.Add

2.Clear

3.Contains

4.IndexOf

5.Insert

6.Remove

7.RemoveAt

结束


一、需求

微软官方的 List 在命名空间 System.Collections.Generic 中,在平时的开发中 List 用的特别多,在用的时候我们基本不会考虑在 List 中内部是怎么写的,于是,我也写了一个List,想看看是否能实现和微软官方一样的功能,当然,不是说为了和微软比比谁写的好,也没那个必要,原创轮子等于白费功夫,微软的API基本已经优化的很好了,直接拿来用就行了,我写这篇文章目的只是为了更了解 List 内部的构造,提升自己 C# 基础,功能当然不可能有官方那么多。

二、List 常用功能

Capacity

        用于获取或设置List可容纳元素的数量。当数量超过容量时,这个值会自动增长。您可以设置这个值以减少容量,也可以调用trin()方法来减少容量以适合实际的元素数目。

Count

        获取List中当前元素数量

Item

        通过指定索引获取或设置元素。对于List类来说,它是一个索引器。

Add 

        在List中添加一个对象

AddRange

        在List尾部添加实现了ICollection接口的多个元素

BinarySearch 

        用于在排序的List内使用二分查找来定位指定元素.

Clear

        移除List所有元素

Contains

        测试一个元素是否在List内

CopyTo

        把一个List拷贝到一维数组内

Exists

        测试一个元素是否在List内

Find 

        查找并返回List内的出现的第一个匹配元素

FindAll

        查找并返回List内的所有匹配元素

GetEnumerator

        返回一个用于迭代List的枚举器

Getrange

        拷贝指定范围的元素到新的List内

IndexOf

        查找并返回每一个匹配元素的索引

Insert

        在List内插入一个元素

InsertRange

        在List内插入一组元素

LastIndexOf

        查找并返回最后一个匹配元素的索引

Remove

        移除与指定元素匹配的第一个元素

RemoveAt

        移除指定索引的元素

RemoveRange

        移除指定范围的元素

Reverse

        反转List内元素的顺序

Sort 

        对List内的元素进行排序

ToArray

        把List内的元素拷贝到一个新的数组内

三、自定义List

自定义 List 如下,我将常用的功能封装了一下

public class TList<T>
{
    private const int _defaultCapacity = 4;
    private static readonly T[] _emptyArray;
    private T[] _items;
    private int _size;
    private int _version;

    public int Capacity
    {
        get => this._items.Length;
        set
        {
            if (value < this._size)
            {
                throw new ArgumentOutOfRangeException("容量太小");
            }
            if (value != this._items.Length)
            {
                if (value > 0)
                {
                    T[] destinationArray = new T[value];
                    if (this._size > 0)
                    {
                        Array.Copy(this._items, 0, destinationArray, 0, this._size);
                    }
                    this._items = destinationArray;
                }
                else
                {
                    this._items = _emptyArray;
                }
            }
        }
    }
    
    public int Count => this._size;

    public T this[int index]
    {
        get
        {
            if (index >= this._size)
            {
                throw new ArgumentOutOfRangeException("index不能大于等于数组的长度");
            }
            return this._items[index];
        }
        set
        {
            if (index >= this._size)
            {
                throw new ArgumentOutOfRangeException("index不能大于等于数组的长度");
            }
            this._items[index] = value;
            this._version++;
        }
    }

    /// <summary>
    /// 添加对象到 List 中
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public int Add(object value)
    {
        if (this._size == this._items.Length)
        {
            this.EnsureCapacity(this._size + 1);
        }
        int index = this._size;
        this._size = index + 1;
        this._items[index] = (T)value;
        this._version++;
        return _size;
    }

    /// <summary>
    /// 从 List 中移除所有项
    /// </summary>
    public void Clear()
    {
        if (this._size > 0)
        {
            Array.Clear(this._items, 0, this._size);
            this._size = 0;
        }
        this._version++;
    }

    /// <summary>
    /// List 中是否包含指定的值
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    public bool Contains(object item)
    {
        if (item == null)
        {
            for (int j = 0; j < this._size; j++)
            {
                if (this._items[j] == null)
                {
                    return true;
                }
            }
            return false;
        }
        for (int i = 0; i < this._size; i++)
        {
            if (_items[i].Equals(item))
            {
                return true;
            }
        }
        return false;
    }

    /// <summary>
    /// 拷贝数组到 List 中指定的位置
    /// </summary>
    /// <param name="array"></param>
    /// <param name="arrayIndex"></param>
    public void CopyTo(T[] array, int arrayIndex)
    {
        Array.Copy(this._items, 0, array, arrayIndex, this._size);
    }

    /// <summary>
    /// 获取 List 中特定项的索引
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public int IndexOf(object value)
    {
        return Array.IndexOf<T>(this._items, (T)value, 0, this._size);
    }

    /// <summary>
    /// 从 List 中的指定索引处插入一个值
    /// </summary>
    /// <param name="index"></param>
    /// <param name="value"></param>
    public void Insert(int index, object value)
    {
        if (index > this._size)
        {
            throw new ArgumentOutOfRangeException("index不能大于数组长度");
        }
        if (this._size == this._items.Length)
        {
            this.EnsureCapacity(this._size + 1);
        }
        if (index < this._size)
        {
            Array.Copy(this._items, index, this._items, index + 1, this._size - index);
        }
        this._items[index] = (T)value;
        this._size++;
        this._version++;
    }

    /// <summary>
    /// 从 List 中移除特定对象的第一个匹配项
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    public bool Remove(T item)
    {
        int index = this.IndexOf(item);
        if (index >= 0)
        {
            this.RemoveAt(index);
            return true;
        }
        return false;
    }

    /// <summary>
    /// 移除位于指定索引处的 List 项。
    /// </summary>
    /// <param name="index"></param>
    public void RemoveAt(int index)
    {
        if (index >= this._size)
        {
            throw new ArgumentOutOfRangeException("index不能大于等于数组的长度");
        }
        this._size--;
        if (index < this._size)
        {
            Array.Copy(this._items, index + 1, this._items, index, this._size - index);
        }
        this._items[this._size] = default(T);
        this._version++;
    }

    private void EnsureCapacity(int min)
    {
        if (this._items.Length < min)
        {
            int num = (this._items.Length == 0) ? 4 : (this._items.Length * 2);
            if (num > 0x7fefffff)
            {
                num = 0x7fefffff;
            }
            if (num < min)
            {
                num = min;
            }
            this.Capacity = num;
        }
    }

    static TList()
    {
        _emptyArray = new T[0];
    }

    public TList()
    {
        this._items = _emptyArray;
    }

    public TList(int capacity)
    {
        if (capacity < 0)
        {
            throw new ArgumentOutOfRangeException("List长度不能小于0");
        }
        if (capacity == 0)
        {
            this._items = _emptyArray;
        }
        else
        {
            this._items = new T[capacity];
        }
    }
}

  

四、测试

1.Add

功能:向 List 内添加对象

namespace 计算1
{
    class Program
    {
        static void Main(string[] args)
        {
            TList<int> list = new TList<int>();
            list.Add(15);
            list.Add(62);
            list.Add(23);
            Console.WriteLine("长度:" + list.Count);
            Console.ReadKey();
        }
    }
}

输出

2.Clear

功能:清除 List 内所有的对象

namespace 计算1
{
    class Program
    {
        static void Main(string[] args)
        {
            TList<int> list = new TList<int>();
            list.Add(15);
            list.Add(62);
            list.Add(23);
            Console.WriteLine("长度:" + list.Count);
            list.Clear();
            Console.WriteLine("长度:" + list.Count);

            Console.ReadKey();
        }
    }
}

输出

3.Contains

功能:LIst 是否包含指定的值

namespace 计算1
{
    class Program
    {
        static void Main(string[] args)
        {
            TList<int> list = new TList<int>();
            list.Add(15);
            list.Add(62);
            list.Add(23);

            bool res = list.Contains(15);
            Console.WriteLine("是否包含:" + res);

            Console.ReadKey();
        }
    }
}

输出

4.IndexOf

功能:获取 List 中特定项的索引

namespace 计算1
{
    class Program
    {
        static void Main(string[] args)
        {
            TList<int> list = new TList<int>();
            list.Add(15);
            list.Add(62);
            list.Add(23);

            int index = list.IndexOf(23);
            Console.WriteLine("对应索引:" + index);

            Console.ReadKey();
        }
    }
}

输出

5.Insert

功能:从 List 中的指定索引处插入一个值

namespace 计算1
{
    class Program
    {
        static void Main(string[] args)
        {
            TList<int> list = new TList<int>();
            list.Add(15);
            list.Add(62);
            list.Add(23);
            //Console.WriteLine("长度:" + list.Count);

            list.Insert(1, 45);

            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine(list[i]);
            }

            Console.ReadKey();
        }
    }
}

输出

6.Remove

功能:从 List 中移除特定对象的一个匹配项

namespace 计算1
{
    class Program
    {
        static void Main(string[] args)
        {
            TList<int> list = new TList<int>();
            list.Add(15);
            list.Add(62);
            list.Add(23);
            list.Add(45);

            bool res = list.Remove(23);
            Console.WriteLine("移除结果:" + res);

            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine(list[i]);
            }

            Console.ReadKey();
        }
    }
}

输出

7.RemoveAt

功能:移除位于指定索引处的 List 项

namespace 计算1
{
    class Program
    {
        static void Main(string[] args)
        {
            TList<int> list = new TList<int>();
            list.Add(15);
            list.Add(62);
            list.Add(23);
            list.Add(45);

            list.RemoveAt(2);

            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine(list[i]);
            }

            Console.ReadKey();
        }
    }
}

输出

结束

如果这个帖子对你有用,欢迎 关注 + 点赞 + 留言,谢谢

end

有关C# 自定义List的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  4. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  5. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  6. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  7. ruby - 如何在 Grape 中定义哈希数组? - 2

    我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>

  8. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  9. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  10. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

随机推荐