在C#中不能将指针数组放在不安全的结构中的根本原因是什么?

时间:2010-05-03 09:32:21

标签: c# pointers d unsafe struct

如果可以将C#中的不安全结构体中的子结构指针数组放入C中,那么构建复杂的数据结构而不会产生每个节点有一个对象的开销,这将更容易,而且时间更少,以及语法更清晰,更具可读性。

是否存在深层架构原因,为什么不安全结构中的固定数组只允许由“值类型”而不是指针组成?

我假设只有在结构体内明确命名指针必须是故意削弱语言的决定,但我找不到任何关于为什么会这样做的文档,或者不允许指针数组在结构体内的原因,因为我会假设垃圾收集器不应该关心标记为不安全的结构中发生了什么。

Digital Mars'D优雅地处理结构和指针,我发现我无法快速开发简洁的数据结构;通过在C#中引用抽象,很多功能似乎已从语言中删除,即使指针至少仍然存在于营销意义上。

也许我错误地认为语言能够在一段时间内有效地表示复杂的数据结构。

3 个答案:

答案 0 :(得分:4)

一个非常简单的原因:dotNET有一个压缩垃圾收集器。它会移动东西。因此,即使你可以创建这样的数组,你也必须 pin 每个已分配的块,你会看到系统慢下来爬行。

但是你正在尝试根据假设进行优化。 dotNET中对象的分配和清理是高度优化的。因此,首先编写一个工作程序,然后使用分析器找到您的瓶颈。它很可能不是你的对象的分配。

编辑,回答后一部分:

  

也许我错误地期待语言   在代表方面变得更加强大   复杂的数据结构有效   随着时间的推移。

我认为C#(或任何托管语言)在表示方面更强大 复杂的数据结构(有效)。通过从低级指针更改为垃圾回收引用。

答案 1 :(得分:2)

我只是在猜测,但它可能与不同目标平台的不同指针大小有关。似乎C#编译器直接使用元素的大小进行索引计算(即,没有CLR支持来计算固定大小的缓冲区索引......)

无论如何,你可以使用ulong的数组并将指针强加给它:

unsafe struct s1
{
  public int a;
  public int b;
}

unsafe struct s
{
  public fixed ulong otherStruct[100];
}

unsafe void f() {
  var S = new s();
  var S1 = new s1();
  S.otherStruct[4] = (ulong)&S1;
  var S2 = (s1*)S.otherStruct[4];
}

答案 2 :(得分:1)

在结构中放置一个固定的指针数组很快就会使它成为结构的不良候选者。结构的建议大小限制是16个字节,所以在x64系统上,你只能在数组中装入两个指针,这是毫无意义的。

您应该使用复杂数据结构的类,如果您使用结构,它们的使用非常有限。例如,您不能在方法中创建数据结构并返回它,因为它将包含指向不再存在的结构的指针,因为它们是在方法的堆栈框架中分配的。