C#-使用数组创建自定义列表时的最佳实践是什么

C#-使用数组创建自定义列表时的最佳实践是什么,c#,arrays,list,oop,generics,C#,Arrays,List,Oop,Generics,我有一些学校作业来练习一些概念,比如泛型、委托和接口。整个项目是使用T数组构建一个自定义列表类。 该类还应该实现IEnumerable,并具有一个结构,该结构是IEnumerator。这里我只关注Add方法 class MyList<T> : IEnumerable { private static readonly T[] arrayStarter = new T[1]; private int capacity = 1; private int curre

我有一些学校作业来练习一些概念,比如泛型、委托和接口。整个项目是使用
T
数组构建一个自定义列表类。 该类还应该实现
IEnumerable
,并具有一个结构,该结构是
IEnumerator
。这里我只关注Add方法

class MyList<T> : IEnumerable
{
    private static readonly T[] arrayStarter = new T[1];
    private int capacity = 1;
    private int currentItems = 1;

    public T[] TList { get; set; }

    public MyList()
    {
        TList = arrayStarter;
        TList[0] = default(T);
    }

    public  T[] Add(T[] tArray, T item)
    {
        T[] temp = new T[++capacity];
        for (int i = 0; i < tArray.Length; i++)
            temp[i] = tArray[i];
        temp[tArray.Length] = item;
        currentItems++;
        return temp;
    }
}
类MyList:IEnumerable
{
私有静态只读T[]arrayStarter=new T[1];
私人内部容量=1;
私有int currentItems=1;
公共T[]TList{get;set;}
公共MyList()
{
TList=阵列启动程序;
TList[0]=默认值(T);
}
公共T[]添加(T[]tArray,T项)
{
T[]温度=新的T[++容量];
for(int i=0;i
当我创建列表的实例时,我希望使用以下方法添加项目:

MyList<int> m = new MyList<int>();
m.TList = m.Add(m.TList, 5);
m.TList = m.Add(m.TList, 7);
m.TList = m.Add(m.TList, 13);
m.TList = m.Add(m.TList, 15);
MyList m=new MyList();
m、 TList=m.Add(m.TList,5);
m、 TList=m.Add(m.TList,7);
m、 TList=m.Add(m.TList,13);
m、 TList=m.Add(m.TList,15);

我很确定有更好的方法来创建自定义列表,我希望有人对此有很好的了解。

如果您在ILSpy中或使用ILSpy查看
list
Add()
方法实现,您会看到:

private int _size;
private T[] _items;

public void Add(T item)
{
    if (this._size == this._items.Length)
    {
        this.EnsureCapacity(this._size + 1);
    }
    this._items[this._size++] = item;
    this._version++;
}

private void EnsureCapacity(int min)
{
    if (this._items.Length < min)
    {
        int num = (this._items.Length != 0) ? (this._items.Length * 2) : 4;
        if (num > 2146435071)
        {
            num = 2146435071;
        }
        if (num < min)
        {
            num = min;
        }
        this.Capacity = num;
    }
}
private int\u size;
私人T[]_项目;
公共作废新增(T项)
{
if(this.\u size==this.\u items.Length)
{
此。保证容量(此。_大小+1);
}
此._项目[此._大小+]=项目;
这个;
}
私人无效保证资本(整数最小值)
{
如果(此项长度2146435071)
{
num=2146435071;
}
if(num
如果您查看ILSpy中或使用ILSpy的
列表
添加()
方法实现,您将看到以下内容:

private int _size;
private T[] _items;

public void Add(T item)
{
    if (this._size == this._items.Length)
    {
        this.EnsureCapacity(this._size + 1);
    }
    this._items[this._size++] = item;
    this._version++;
}

private void EnsureCapacity(int min)
{
    if (this._items.Length < min)
    {
        int num = (this._items.Length != 0) ? (this._items.Length * 2) : 4;
        if (num > 2146435071)
        {
            num = 2146435071;
        }
        if (num < min)
        {
            num = min;
        }
        this.Capacity = num;
    }
}
private int\u size;
私人T[]_项目;
公共作废新增(T项)
{
if(this.\u size==this.\u items.Length)
{
此。保证容量(此。_大小+1);
}
此._项目[此._大小+]=项目;
这个;
}
私人无效保证资本(整数最小值)
{
如果(此项长度2146435071)
{
num=2146435071;
}
if(num
此实现表明,您缺少一般的封装,尤其是使用私有成员。由于您将
TList
array作为列表类的成员,因此您可以对用户完全隐藏它。您的用户应该能够编写

m.Add(5);
m.Add(7);
而不是

m.TList = m.Add(m.TList, 5);
m.TList = m.Add(m.TList, 7);
而且根本不用担心m.TList的存在

幸运的是,您可以很容易地做到这一点:将
TList
设为私有字段,将其重命名为以小写字母开头的字段,将其从
Add
的参数列表中删除,并更改
Add
以不返回任何内容。这将匹配您应该考虑实现的签名。

一旦你做了这项工作,考虑“离婚”<代码>容量>代码> >代码> CurrimeTimes ,让第一个增长更快,另一个赶上更多的条目。这将减少重新分配的次数


作为最后一点,考虑切换到使用以避免手动复制数据。

此实现表明,您一般缺少封装的点,特别是使用私有成员。由于您将

TList
array作为列表类的成员,因此您可以对用户完全隐藏它。您的用户应该能够编写

m.Add(5);
m.Add(7);
而不是

m.TList = m.Add(m.TList, 5);
m.TList = m.Add(m.TList, 7);
而且根本不用担心m.TList的存在

幸运的是,您可以很容易地做到这一点:将
TList
设为私有字段,将其重命名为以小写字母开头的字段,将其从
Add
的参数列表中删除,并更改
Add
以不返回任何内容。这将匹配您应该考虑实现的签名。

一旦你做了这项工作,考虑“离婚”<代码>容量>代码> >代码> CurrimeTimes ,让第一个增长更快,另一个赶上更多的条目。这将减少重新分配的次数


作为最后一点,考虑切换到使用,以避免手动复制数据。

如果新的大小超过容量,则应该将数组的大小增加一倍。您不应该返回阵列,它只是一个内部存储器。提供一个索引器。应该没有必要,甚至不可能,将其分配给list类的
TList
属性。这应该是私人的,外部世界无法进入。不过你已经进入了舆论领域。我相信这个问题会更适合你。你也可以考虑执行<代码> IIST < /COD>及其通用变体,除了
IEnumerable
之外,它还可以用于更多的地方。让列表包含初始默认项是一件奇怪的事情……当我看到如何添加项时,首先想到的是:
add
方法的签名看起来像一个扩展方法,它不是类的一部分。这看起来有问题。如果新大小超过容量,则应将阵列大小增加一倍。您不应该返回阵列,它只是一个内部存储器。提供一个索引器。应该没有必要,甚至不可能,分配给你的列表类的
TList