将数组扩展一个

Expanding an array by one

我有一个 class filtercollection,其中包含一组过滤器:

class TransactionTypeFilterCollection
{
    public CategoryNode FilterCollection { get; private set; }
    public TransactionTypeFilter[] Filters { get; private set; }
    public void AddFilter(string field, FilterOperator filterOperator, string value)
    {
        TransactionTypeFilter newFilter = new TransactionTypeFilter(
            filterCollection: this.FilterCollection,
            name: this.FilterCollection.Name + "_Filter_" + this.Filters.Length,
            field: field,
            filterOperator: filterOperator,
            value: value
        );
        TransactionTypeFilter[] newFilterCollection = new TransactionTypeFilter[this.Filters.Length+1];
        Array.Copy(this.Filters, 0, newFilterCollection,0, this.Filters.Length);
        newFilterCollection[this.Filters.Length] = newFilter;
        this.Filters = newFilterCollection;
    }
}

具体来说,我没有使用 List,因为如果不访问 Filter Collection 的正确功能,就无法轻易地从外部 added/removed 元素。同样出于性能原因。

我觉得这段扩展数组的代码有点麻烦,而且“感觉”不对:

TransactionTypeFilter[] newFilterCollection = new TransactionTypeFilter[this.Filters.Length+1];
Array.Copy(this.Filters, 0, newFilterCollection,0, this.Filters.Length);
newFilterCollection[this.Filters.Length] = newFilter;
this.Filters = newFilterCollection;

我通常会做如下事情:

List<TransactionTypeFilter> newFilterCollection = this.Filters.ToList();
newFilterCollection.Add(newFilter);
this.Filters = newFilterCollection.ToArray();

但是基准测试表明 array.Copy 快了 3 倍~ 并且方法 2 的结果随着我要​​添加的元素越多而变得越差。

即使在我添加元素的平面列表中,方法 1 也更快。

有没有更好的扩展数组的方法?

我在 Is it possible to extend arrays in C#? 中找到了答案,但在 class 中尝试 Array.Resize 时,我收到编译器错误:A property or Indexer may not be passed as out or ref parameter.

您是否正确传递了引用参数?该错误表明您正试图传入 属性。属性不是变量,因此不能作为输出参数传递。这可能适用于您的用法

private static Array ResizeArray(Array arr, int[] newSizes)
{
   var temp = Array.CreateInstance(arr.GetType().GetElementType(), newSizes);
   int length = arr.Length <= temp.Length ? arr.Length : temp.Length;
   Array.ConstrainedCopy(arr, 0, temp, 0, length);
   return temp;
}