【问题标题】:Create an array/List of structures when structure contains an array/List当结构包含数组/列表时创建一个数组/结构列表
【发布时间】:2011-07-13 00:17:19
【问题描述】:

我是 C# 新手,通常是 C 程序员,所以我无法找出最佳使用方法。希望我能得到一些建议来帮助我做出决定。
我有一个看起来像这样的结构(我在 C 中是这样做的):

struct structData
{
    long type;
    long myArray[50];
    string text;
}

我创建了一个由这些结构组成的数组,我可以在全局/公开范围内不断地读/写。 (我需要将数据存储在那里,以便以后可以访问)

structData arrayOfStructs[50];  

目标是像这样访问数据:

arrayOfStructs[0].type = 123;
arrayOfStructs[0].myArray[0] = 456;

当我尝试在 C# 中实现此功能时,会遇到各种错误:
myArray”需要固定为50,但需要在不安全区域
如果我尝试初始化它“... = new ...”我会得到一个错误

首先,我应该使用 List 而不是数组吗?有性能差异吗?
其次,我应该创建一个类而不是结构,在构造函数中初始化数组,然后创建对象的列表/数组吗?您将如何实现这一点?
是的,我需要使用 longs。

【问题讨论】:

  • 发布其余代码,包括您的数组初始化
  • 语法相似并不意味着你应该用 C# 编写 C 代码。
  • 我不是想用 C# 编写 C,我只是说我将如何在 C 中做到这一点,而不是我应该做的。这就是为什么我问我应该怎么做。

标签: c# arrays list struct


【解决方案1】:
public class StructData
{
    public long type;
    public long[] myArray = new long[50];
    public string text;
}

StructData[] datas = new StructData[100];

for (int i = 0; i < datas.Length; i++)
{
    datas[i] = new StructData();
}

对大对象使用类,对小且可能不可变的“对象”使用结构(假设结构应该小且不可变。它们可以是你想要的任何东西) 需要明确的是,我在 .NET 中所知道的最大结构由 4 个 int 组成(它是 Guid)。我认为这是小型与大型结构的良好基准。

如果您需要扩展您的集合,请使用 List,如果大小固定,请使用数组,List 并不比数组慢多少(它们在内部使用数组)。我不知道是否有人曾经将数组作为 List 的基准。 List 通常比数组使用更多的内存,因为它保留了一点空间来扩大集合(并且它保留了 List 的当前大小和指向内部数组的指针,也许还有其他数据。所以它至少大一个 int 和一个指针,加上所有对象的 std 开销)。您可以通过将要保留的元素数量传递给构造函数来“调整”列表的大小。

【讨论】:

  • 尝试写入数组时出现错误。我使用了这一行:datas[0].type = 123;
  • @Nick 您必须初始化数据的单个元素。结构数据 [] 数据 = 新结构数据 [100];初始化数组(容器),但您必须初始化单个元素。在示例中添加了这些行。
【解决方案2】:

所以,我首先要说的是,你应该避免用 C# 编写 C 代码的诱惑。除了明显的语法相似性之外,这两种语言几乎没有共同点。

在 C# 中,您很少使用结构。结构的语义不同于类的语义。以下是关于何时使用 struct v 何时使用类的简要说明。有更多可用资源,我只是抓住了第一个与该主题相关且似乎合理的结果:When to use a struct

其次,是的,您应该尽可能使用通用容器类型。性能不会成为问题,从长远来看,它会让你的生活变得更轻松。您声明数组的语法已关闭(它与 C 不同)并且应该是:

long[] myArray = new long[50];

如果您需要将数组固定在内存中以进行互操作,您可以通过 fixed 关键字完成此操作,但是当您将托管数组传递给本机函数时,互操作层实际上会为您完成此操作。

我建议您花一些时间从头开始学习 C#,忘记语法与 C 相似的事实。它们是完全不同的语言,具有完全不同的语义和最佳实践。

【讨论】:

    【解决方案3】:

    如果您需要本机互操作性,也就是说,您要通过某种机制来编组这些类型或简单地围绕字节数组进行强制转换,那么您需要这种不安全/固定的东西,并且可以这样完成。

    unsafe struct structData 
    {     
        int type;
        fixed int myArray[50]; // long is 64-bit in C# was that intentional?
        string text; // string is a managed type
    }
    

    来自 C 的您绝对不应该将 C 代码直接翻译成 C# 等价物,因为这没有什么意义。在 C# 中,事物是托管的,您通常会接受与托管代码相关的成本,并且不考虑该级别的性能影响,反正一开始也不考虑。

    研究 C# 的内存模型是一个很好的起点,因为它解释了值类型和引用类型之间的许多细微但重要的区别。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多