【问题标题】:Expanding an array by one [closed]将数组扩展一[关闭]
【发布时间】:2022-01-09 07:35:22
【问题描述】:

我有一个类 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,因为如果不访问过滤器集合的正确功能,就无法轻松地从外部添加/删除元素。也出于性能原因。

这个扩展数组的代码让我觉得有些麻烦,而且“感觉”不太对:

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#? 中找到了答案,但在我的课堂上尝试Array.Resize 时,我收到编译器错误:A property or Indexer may not be passed as out or ref parameter

【问题讨论】:

  • 对我来说看起来像是一个微优化。在最坏的情况下,您在该数组中存储了多少元素?
  • 顺便说一下,List&lt;T&gt; 有一个容量属性或一个构造函数参数,允许您在不调整大小的情况下给出列表中的大致元素数量。您是否使用此选项进行基准测试?
  • 出于性能原因,您不想使用List&lt;&gt;,因此您找到了一个性能更高的解决方案,但它并不“感觉”正确,无论这意味着什么。所以你想要什么?你不能两全其美。 Array.Resize() 确实是要走的路,尽管您可能会发现必须将 this.Filters 复制到一个临时变量中,这样您就可以通过 reference 传递它,就像 Array.Copy() 方法一样“麻烦”。
  • 我投票结束这个问题,因为它属于codereview.stackexchange.com

标签: c# arrays list extending


【解决方案1】:

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

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 2013-04-02
    • 1970-01-01
    • 2013-01-24
    相关资源
    最近更新 更多