【问题标题】:How to apply Array.Sort to Collection<T>?如何将 Array.Sort 应用于 Collection<T>?
【发布时间】:2019-10-24 21:27:19
【问题描述】:

我有一个集合(集合有点大 > 100K 自定义复杂项目,并且经常添加新项目)。 我只需要对它进行一次排序 - 在显示它之前。 为了简化我的问题,假设我有一个需要排序的整数集合:

private static void Main(string[] args)
{
    var collection = new Collection<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    var list = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    var array = new [] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

    // How to apply Array.Sort to Collection<T> ?
    list.Sort();       //ok
    Array.Sort(array); //ok
}

基本上list.Sort(); 使用Array.Sort&lt;T&gt;(this._items, index, count, comparer);

如何对我的Collection&lt;T&gt; 进行排序? (不复制)

【问题讨论】:

  • 我无法理解你不能使用 list.sort() 的原因
  • @AntonioGanci 因为Collection&lt;T&gt; 不是List&lt;T&gt;,而Collection&lt;T&gt; 没有Sort()?
  • @AntonioGanci 原因是 Microsoft 规则 CA 1002(警告 CA1002 更改 'IMyInterface.MyList' 中的 'List' 以使用 Collection、ReadOnlyCollection 或 KeyedCollection)
  • @isxaker 我会禁止这条规则,老实说......这样的事情仅适用于你是一个图书馆作者,他正在运送图书馆以供其他人使用伙计们,即便如此还是有问题的;如果您是 app 开发人员(即您的代码仅用于您自己的系统或您的同事可以轻松调整的系统):忘记它
  • 忽略“规则”。

标签: c# arrays .net list collections


【解决方案1】:

没有方便的方法来做到这一点; Collection&lt;T&gt; 不提供对内部缓冲区的原始访问,即使是子类 (protected)。没有它,您将无法进行干净的就地排序。

您可以在底层.Items (protected) 上手动实现排序,但工作量很大且效率低下。

你可以做的还有:

  • 从阵列池中租用一个阵列
  • 将本地集合中的数据复制到租用的数组中
  • 对该数组进行排序
  • 要么从现在排序的数组中清除并重新添加所有内容,要么从现在排序的数组中逐个索引地覆盖项目
  • 将租用的阵列归还阵列池

但是,我个人可能会说“如果您需要排序,请使用List&lt;T&gt;” - 它会为您节省大量工作。

【讨论】:

  • *从数组池中租用一个数组*——从未听说过 C# 数组以这种方式谈论。我明白了它的要点,但这是官方术语还是方便的隐喻还是......?
  • @D.BenKnoble 示例:int[] leasedArray = ArrayPool&lt;int&gt;.Shared.Rent(minimumSize); /* TODO: use it ... */ ArrayPool&lt;int&gt;.Shared.Return(leasedArray); 等 - 请注意,租用的数组超大(即,如果您要求的数组至少为 100,它可能会借给你一码 128) - 这是来自 System.Buffers
  • 我明白了...有什么理由这样做,而 不 new T[size] 因为尺寸是已知的?
  • @d.benknoble 原因在于性能,因为池中的内存可能已经分配了一块内存,而您只是在租用它。想想租一套公寓还是从头开始建造一套;)
  • @D.BenKnoble 分配;越少越好
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-25
  • 2016-10-11
  • 2010-09-30
  • 1970-01-01
  • 2010-10-06
  • 2010-09-21
相关资源
最近更新 更多