我需要一个公开数组的动态集合类型

本文关键字:数组 动态 集合 类型 集合类 一个 | 更新日期: 2023-09-27 18:24:42

我需要一个集合类型,它将按照添加的顺序存储数组中的所有内容,它需要动态增加大小,并且它需要将数组公开为公共字段/属性以供读取。

我已经确定c#List.ToArray()对我来说太贵了。

有符合我要求的收藏类型吗?如果没有,你能把我介绍给一个允许我这样做的自定义类吗?

编辑:为了添加更多信息,我为人们提供了基准ToArray(),目的是将结构数组发送到图形卡,以便它可以渲染顶点。如果你想知道我为什么需要这个数组,那就是为什么。

Edit2:缓冲区保留在CPU上,每帧都会发送到GPU,因为它经常变化,但大小并不经常变化。

我需要一个公开数组的动态集合类型

您对文章的第二次编辑给出了解决方案。

给定以下要求和限制:

  • 集合必须提供对(底层)阵列的快速访问,因为它用于GPU的动态使用(访问每帧)
  • 它的内容经常会被修改,但大小不会被修改
  • 它有时会调整大小(不经常)

第一个和最后一个要求让我认为,在您的情况下,数组仍然是最好的解决方案(而List在频繁调整大小的情况下(由于其容量属性)很有趣)。

现在,要"调整"数组的大小,有两种可能性:

  1. Array.Resize()(如果需要保留上一个数组中的数据)
  2. 如果不需要以前的数据,则创建新阵列
public class MyList<T> : List<T>
{
    private FieldInfo _finfo = 
         typeof(List<T>)
         .GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);
    public T[] Items
    {
        get
        { 
            return (T[])_finfo.GetValue(this);
        }
    }
}

我需要一个集合类型,它将在按照添加顺序,它需要动态增加大小需要将数组公开为用于读取的公共属性。

您可以简单地使用List<object>,在需要数组的地方,使用它的ToArray(..)调用。

编辑

如果由于某种原因ToArray(..)对您不好("太贵"),您可以使用相同的对象通过索引访问它。如果这是您的实际要求。

如果这不是你想要的,请澄清。

编辑

考虑到您谈论的是GPU交互,因此您有非常大的具有3D数据的顶点阵列,我建议使用C#提供的简单Array,并使用带有*指针的不安全代码,如果可能的话,在您的情况下(我不知道GPU侧的调用方法的签名)。

因此,将不会有任何动态分配,这必须由您的代码根据请求进行处理。

除非数组是巨大的,否则单个副本不会花费太多,就像大型对象堆一样。唯一不正确的情况是,如果你试图为Windows Phone或Xbox 360编写游戏,垃圾收集会被阻止,需要很长时间。

在这种情况下,我建议创建一个比您需要的大得多的静态阵列,并将其传递给具有适当长度的GPU。

如果你给我们更多的细节,我可以就如何避免额外的开销提出更多的建议。如果您可以使用unsafe,我建议您研究内存映射缓冲区,并直接使用它提供的指针。但是,如果不重新分配缓冲区,就无法调整它的大小,所以请确保它足够大。

示例,使用OpenGL:

unsafe
{
    glBindBuffer(GL_ARRAY_BUFFER, myBuffer);
    float* bufferPtr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
    // Update the buffer here, reading and writing to the pointer.
    glUnmapBuffer(GL_ARRAY_BUFFER);
}

我对Direct3D不太熟悉,所以我不能给你示例代码,但它会非常相似。