6

如果可以像在 C# 中那样将一组指向子结构的指针放在 C# 中的不安全结构中,那么构建复杂的数据结构而无需每个节点拥有一个对象的开销会容易得多,而且耗时更少,并且语法更清晰,可读性更强。

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

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

相比之下,Digital Mars 的 D 优雅地处理结构和指针,我错过了不能快速开发简洁的数据结构;通过在 C# 中使引用抽象化,语言似乎已经消除了很多功能,即使指针至少在营销意义上仍然存在。

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

4

3 回答 3

4

一个非常简单的原因:dotNET 有一个压缩垃圾收集器。它移动东西。因此,即使您可以创建这样的数组,您也必须固定每个分配的块,并且您会看到系统减速到爬行。

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

编辑,回答后半部分:

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

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

于 2010-05-03T09:42:11.187 回答
2

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

无论如何,您可以使用 s 数组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];
}
于 2010-05-03T10:08:50.743 回答
1

在结构中放置一个固定的指针数组会很快使其成为结构的不良候选者。结构体的推荐大小限制为 16 字节,因此在 x64 系统上,您只能在数组中放置两个指针,这是毫无意义的。

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

于 2010-05-03T10:02:10.267 回答