如何在结构中声明结构数组
本文关键字:结构 声明 数组 | 更新日期: 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通过组合X
和Y
值来构造Point
,this[int]
setter存储传入点的X和Y值。this[int]
getter从其中一个字段中读取,并让this[int]
setter写入其中一个。有一些方法可以使其效率不太低,但它仍然相当恶心。get
和set
访问者应该看起来像:
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
访问器时,都必须制作阵列的新副本。然而,如果写入的频率远低于读取,那么这可能不是问题。顺便说一句,正如所写的,代码应该是完全线程安全的——这在可变结构中是可能的,但在假装不可变的结构中是不可能的。