C#,如何处理常量表

时间:2009-09-03 23:55:39

标签: c# constants

这种语言显然没有合适的功能,这似乎很奇怪。

我发现自己的数据最好被表达为一个多维数组,但它完全不变,没有任何人可以在不改变相关代码的情况下改变它。面对Delphi中的这些东西,答案是显而易见的 - 一个常量,其值是表。但是,C#似乎不支持这样的东西。

谷歌显示很多人对此抱怨,没有好的答案。

人们如何处理这种情况?

(并且不要说常量不属于代码 - 我碰到的最后一个是4个项目的所有可能的排列。除非时空的性质发生变化,否则这就是一成不变的。)

发生了什么事?有一个答案非常接近,我问的是一个细节,它消失了!简单地声明一个数组排序工作 - 唯一的问题是数组分配将每次运行。我前面的那个包含96个值 - 如何让它只初始化一次?我是否只需要接受范围远大于应有范围的范围? (因为它在一个3行程序中,它在O(n ^ 3)程序中。)

6 个答案:

答案 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"),
    };