如何在结构中声明结构数组

本文关键字:结构 声明 数组 | 更新日期: 2023-09-27 18:19:49

使用Visual Studios 2010 C#

因此,我正在为一个c项目制作一个数据结构,它的成员中将包括另一个结构类型的数组。例如,这里是我的代码的一个精简想法:

    private struct scores
    {
        public double finalScore;

    };
    private struct information
    {
        public string name;
        public scores[] scoreList;
    };

当我写这篇文章时,我收到了以下警告:

错误1"WindowsFormsApplication1.main.informations.scoreList":无法在结构中具有实例字段初始化程序

我想知道声明结构信息的scores[]scoreList方面的正确方法是什么,这样我就可以将数组大小设置为10?

我尝试过的东西:

  • 如果我尝试

    公共分数[]scoreList=新分数[10]

我得到以下错误

错误1"WindowsFormsApplication1.main.informations.scoreList":无法在结构中具有实例字段初始化程序

如何在结构中声明结构数组

在结构中,您只能在构造函数中进行初始化:

  struct information {
    public string name;
    public scores[] scoreList;
    // Constructor
    public information(String nameValue) {
      name = nameValue;
      scoreList = new scores[10]; // <- It's possible here
    }
  };

这里的问题是您将结构设置为私有结构,这意味着您不能创建它们的实例。公开它们。并且还要摆脱;最后

public struct scores
{
    public double finalScore;

}
public struct information
{
    public string name;
    public scores[] scoreList;
}

我通常不使用structs,因为它们的OO限制以及它们不可为null的事实。然而,.Net中有几个结构:DateTime、int、float等。

你不能这么做。原因是结构是值类型。结构的默认构造函数是一个无参数构造函数,它将所有字段初始化为默认值。您无法控制此构造函数,因为它们是值类型。

显示这一点的最佳方式是例如通过数组。假设您制作了一个类类型的数组,例如new object[10]。此数组的项将被初始化为null。然而,当您制作一个结构数组时,例如new information[10],数组中的项将已经是有效的实例。但是,这些项的构造函数将不会运行,并且所有字段都将初始化为空值。在您的情况下,这意味着所有字段都将是null

对此有两种解决方案。第一个解决方案是创建一个工厂方法,例如:

public static information CreateNew()
{
    var result = new information();
    result.scoreList = new scores[10];
    return result;
}

这会奏效的。您只需使用information.CreateNew()而不是new information()创建一个实例,就会有一个初始化的information。然而,一个更简单的解决方案是只使用class

有三种方法可以使结构表现为结构的值类型数组:

  • 使用unsafe代码在结构中包含一个或多个fixed基元数组;让索引的get/put访问器用存储在这些数组中的信息组装一个结构。例如,如果您想表现得像Point的数组,那么可以为所有X坐标设置一个fixed数组,为所有Y坐标设置fixed数组,然后让this[int] getter通过组合XY值来构造Pointthis[int] setter存储传入点的X和Y值。
  • 有多个结构类型的字段,让this[int] getter从其中一个字段中读取,并让this[int] setter写入其中一个。有一些方法可以使其效率不太低,但它仍然相当恶心。
  • 让结构持有适当结构类型的私有数组。getset访问者应该看起来像:
    T[] _array;
    T this[int index] {
    get {
      T[] temp_array = _array;
      if (temp_array == null) return default(T);
      return temp_array[index];
    }
    set {
      do
      {
        T[] was_array[] = _array;
        T[] new_array = (temp_array == null) ? new T[size] : (T[])(temp_array.Clone());
        temp_array[index] = value;
      } while (System.Threading.Interlocked.CompareExchange(ref _array, new_array, was_array) !=
        was_array);
    }};
    

    这种方法将允许get索引器比第二种方法(可能还有第一种方法)运行得更快,而且与第一种方法不同,它将使用泛型类型。这种方法的主要弱点是,每次运行其set访问器时,都必须制作阵列的新副本。然而,如果写入的频率远低于读取,那么这可能不是问题。顺便说一句,正如所写的,代码应该是完全线程安全的——这在可变结构中是可能的,但在假装不可变的结构中是不可能的。