这种语言显然没有合适的功能,这似乎很奇怪。
我发现自己的数据最好被表达为一个多维数组,但它完全不变,没有任何人可以在不改变相关代码的情况下改变它。面对Delphi中的这些东西,答案是显而易见的 - 一个常量,其值是表。但是,C#似乎不支持这样的东西。
谷歌显示很多人对此抱怨,没有好的答案。
人们如何处理这种情况?
(并且不要说常量不属于代码 - 我碰到的最后一个是4个项目的所有可能的排列。除非时空的性质发生变化,否则这就是一成不变的。)
发生了什么事?有一个答案非常接近,我问的是一个细节,它消失了!简单地声明一个数组排序工作 - 唯一的问题是数组分配将每次运行。我前面的那个包含96个值 - 如何让它只初始化一次?我是否只需要接受范围远大于应有范围的范围? (因为它在一个3行程序中,它在O(n ^ 3)程序中。)
答案 0 :(得分:3)
答案 1 :(得分:2)
C# FAQ中有关于此特定内容的页面。
他们建议使用静态只读数组:
static readonly int[,] constIntArray = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }};
但是,请注意,这只是一种常量 - 您仍然可以重新分配数组中的各个元素。此外,这必须在类级别指定,因为它是静态的,但它可以很好地工作。
答案 2 :(得分:1)
您可以使用只读Hashtable。唯一的缺点是readonly不会阻止您更改Hashtable中特定项的值。所以它不是真正的常量。
readonly Hashtable table = new Hashtable(){{1,"One"},{2,"Two"}};
或数组
public readonly string[,] arry = new string[,]{{"1","2"},{"2","4"}};
是的,您需要在适当的范围内声明变量,以便不会多次初始化。
答案 3 :(得分:1)
喜欢他们说,只需添加另一层间接。 C#不需要提供专门的数据结构作为语言原语,尽管有时希望有一种方法可以使任何类不可变,但这是另一种讨论。
现在你没有提到你是否需要存储不同的东西。事实上,你没有提到除了多维之外的任何东西,也没有能力改变数值或数组。我甚至不知道访问模式(单个int,int,int索引器)是否合适。
但总的来说,对于一个三维锯齿状阵列,以下工作(但它并不漂亮)。
一个警告是你构造它的类型也需要是不可变的,但这是你的问题。您只需创建自己的只读包装器即可。
public static readonly ReadOnlyThreeDimensions<int> MyGlobalThree
= new ReadOnlyThreeDimensions<int>(IntInitializer);
public class ReadOnlyThreeDimensions<T>
{
private T[][][] _arrayOfT;
public ReadOnlyThreeDimensions(Func<T[][][]> initializer)
{
_arrayOfT = initializer();
}
public ReadOnlyThreeDimensions(T[][][] arrayOfT)
{
_arrayOfT = arrayOfT;
}
public T this [int x, int y, int z]
{
get
{
return _arrayOfT[x][y][z];
}
}
}
然后你只需要提供一些初始化方法,或者在静态构造函数中指定它。
public static int[][][] IntInitializer()
{
return xyz // something that constructs a [][][]
}
答案 4 :(得分:0)
肯定是枚举。
答案 5 :(得分:0)
好吧,我采取了以下方法,阅读时有点讨厌但很容易编辑。
public struct Something
{
public readonly int Number;
public readonly string Name;
public Something(int num, string name) { this.Number = num; this.Name = name; }
}
public readonly Something[] GlobalCollection = new Something[]
{
new Something(1, "One"),
new Something(2, "Two"),
};