.NET 集合是一个结构体

发布于 2024-10-08 18:29:43 字数 272 浏览 1 评论 0原文

这是一个有趣的问题....net 框架中是否有一个结构体的集合?

只是为了澄清,所有现有的集合(列表、数组等)都是引用类型......即使您将泛型参数设置为值类型。但我想知道是否有一种方法可以创建一个实际上是结构的集合。我显然不打算传递它(这会导致大量复制)...我会将其保留为我的类(内部状态)中的私有成员,因此它只定义一次。我的想法是,我将能够避免调用垃圾收集器来进行小型收集(想想 XNA)。

假设不存在,问题的第二部分是,理想的数据结构是什么。链接列表?

Here's an interesting question ... is there a collection that is a struct somewhere in the .net framework?

Just to clarify, all of the existing collections (List, array, etc.) are all reference types ... even if you set the generic parameter to a value type. But I want to know if there's a way I can make a collection that is actually a struct. I obviously wouldn't plan on passing this around (which would result in a ton of copying) ... I'd keep it as a private member in my class (internal state) so it's only defined once. The idea is that I would be able to avoid invoking the garbage collector just to make a small collection (think XNA).

Assuming one does not exist, a secondary part of the question is, what would be the ideal data structure for this. linked list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绮筵 2024-10-15 18:29:43

不,这样的类型不存在,这不是一个好主意。根据 Microsoft 指南,结构应该是小型的不可变值类型。

来自值类型使用指南

  • 表现得像原始类型。
  • 实例大小小于 16 字节。
  • 不可变。
  • 值语义是可取的。

将链表实现为值类型会很困难,因为链表通常是递归定义的。这工作正常:

class Node<T>
{
    public T Value;
    public Node<T> Next;
}

但这会失败,因为结构具有固定的大小,并且在定义结构时必须知道该大小:

struct Node<T>
{
    public T Value;

    // Error: Struct member 'Node<T>.Next' of type 'Node<T>'
    // causes a cycle in the struct layout
    public Node<T> Next; 
}

No, such a type does not exist and it would not be a good idea. Structs should be small immutable value types according to the Microsoft guidelines.

From the Value Type Usage Guidelines:

  • Act like primitive types.
  • Have an instance size under 16 bytes.
  • Are immutable.
  • Value semantics are desirable.

It would be difficult to implement a linked list as a value type because linked lists are typically defined recursively. This works fine:

class Node<T>
{
    public T Value;
    public Node<T> Next;
}

But this fails because structs have a fixed size and that size must be known when the struct is defined:

struct Node<T>
{
    public T Value;

    // Error: Struct member 'Node<T>.Next' of type 'Node<T>'
    // causes a cycle in the struct layout
    public Node<T> Next; 
}
颜漓半夏 2024-10-15 18:29:43

实际上有一个结构体,它是一个集合。 BitVector32 是一个结构体,其作用类似于 32 个布尔值、或 4 个字节或 2 个短整型的集合。当您想要进行一些操作但又不想过多考虑创建蒙版等内容时,它非常方便。

另外,如果您实际上计划自己推出,请注意,如果您让它实现类似 IList 的东西,您永远不应该将其发送到类似

public static void SomeMethod(IList<Int32> list)
{
       ....
}

As 的代码,这会将其装箱并且每个成员访问很可能会导致装箱,而是将其发送到具有此签名的方法::

public static void SomeMethod<T>(T list) where T:IList<Int32>
{
       ....
}

作为第二个示例,将在每次 callvirt 之前发出 constrained 操作码,这将在调用结构成员时避免装箱。不过祝你好运。

Actually there is a struct that is a collection. BitVector32 is a struct and acts like a collection of 32 booleans, or 4 bytes or 2 shorts. It's pretty handy when you want to do bittwidling but don't want to think too much about creating masks and such.

Also if you actually plan on rolling your own, be warned that if you make it implement something like IList<Int32> you should never send it to code that reads like

public static void SomeMethod(IList<Int32> list)
{
       ....
}

As that will box it and each member access will most likely lead to boxing instead send it to a method that has this signature::

public static void SomeMethod<T>(T list) where T:IList<Int32>
{
       ....
}

As the second example will emit the constrained opcode before each callvirt which will avoid boxing when invoking struct members. Good luck though.

污味仙女 2024-10-15 18:29:43

还有 SPAN ,自 v 2.1 起在 dotNetCore 中

And there is SPAN, in dotNetCore since v 2.1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文