关于c#:声明一个const数组

Declare a const array

是否可以写类似以下内容的东西?

1
public const string[] Titles = {"German","Spanish","Corrects","Wrongs" };


是的,但是您需要声明它是readonly,而不是const

1
public static readonly string[] Titles = {"German","Spanish","Corrects","Wrongs" };

原因是const只能应用于编译时已知值的字段。您所显示的数组初始值设定项不是C中的常量表达式,因此它会产生编译器错误。

声明它readonly解决了这个问题,因为值直到运行时才初始化(尽管它保证在第一次使用数组之前已经初始化)。

根据最终想要实现的目标,还可以考虑声明枚举:

1
public enum Titles { German, Spanish, Corrects, Wrongs };


您可以将数组声明为readonly,但请记住,您可以更改readonly数组的元素。

1
2
3
public readonly string[] Titles = {"German","Spanish","Corrects","Wrongs" };
...
Titles[0] ="bla";

考虑使用枚举,如Cody建议的那样,或IList。

1
public readonly IList<string> ITitles = new List<string> {"German","Spanish","Corrects","Wrongs" }.AsReadOnly();


不能创建"const"数组,因为数组是对象,并且只能在运行时创建,常量实体在编译时解析。

相反,您可以将数组声明为"readonly"。这有除了可以在运行时设置值外,其他效果与const相同。它只能是设置一次,之后为只读(即常量)值。


既然C 6,你可以这样写:

1
public static string[] Titles => new string[] {"German","Spanish","Corrects","Wrongs" };

另请参见:c:新的和改进的c 6.0(特别是"表达式体函数和属性"一章)

这将生成一个只读静态属性,但它仍然允许您更改返回的数组的内容,但当您再次调用该属性时,将再次获得原始的未更改的数组。

为了澄清,此代码与(或实际上是)相同:

1
2
3
4
public static string[] Titles
{
    get { return new string[] {"German","Spanish","Corrects","Wrongs" }; }
}

请注意,这种方法有一个缺点:一个新的数组实际上是在每个引用上实例化的,因此如果您使用的是一个非常大的数组,这可能不是最有效的解决方案。但是,如果您重新使用同一个数组(例如,通过将其放入私有属性),它将再次打开更改数组内容的可能性。

如果要有一个不可变数组(或列表),还可以使用:

1
public static IReadOnlyList<string> Titles { get; } = new string[] {"German","Spanish","Corrects","Wrongs" };

但是,这仍然存在更改的风险,因为您仍然可以将其转换回字符串[],并更改内容,例如:

1
((string[]) Titles)[1] ="French";


您可以采用不同的方法:定义一个常量字符串来表示您的数组,然后在需要时将该字符串拆分为数组,例如。

1
2
const string DefaultDistances ="5,10,15,20,25,30,40,50";
public static readonly string[] distances = DefaultDistances.Split(',');

这种方法为您提供一个常量,该常量可以存储在配置中,并在需要时转换为数组。

阿拉斯泰尔


如果你声明你在ireadonlylist接口阵列在恒定值恒定的数组得到一个不被在运行时:

1
public readonly IReadOnlyList<string> Titles = new [] {"German","Spanish","Corrects","Wrongs" };

可在.NET 4.5和更高。


根据我的需要,我定义了static数组,而不是不可能的const数组,它工作:public static string[] Titles = {"German","Spanish","Corrects","Wrongs" };


NET框架的解决方案A是在tdbeckett v4.5 +创建的回答:

1
2
3
4
5
6
7
using System.Collections.ObjectModel;

// ...

public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
  new string[] {"German","Spanish","Corrects","Wrongs" }
);

注:给定的集合,它可能是conceptually常数的意义,让它在一个static一流水平声明它。

上面:

  • initializes物业的酒店做一次隐场阵列。

    • 注意,只有一{ get; }IU,declaring物业吸气剂是什么使物业本身implicitly只读(试图从一个{ get; }实际上是一readonly语法错误)。

    • 也,你只是omit { get; }和添加的readonly创建一场"物业,在曝光的问题,但作为公共数据成员属性是一个良好的习惯,而不是域的形成。

  • 创建阵列状结构(这是真正的索引允许访问)和robustly只读(conceptually常数,一次,两个背景了):

    • 防止修改的集合作为一个整体(如通过删除或添加元素,或由一个变量分配新的收集)。
    • 防止修改的个人元素。间接修改(甚至不是一个IReadOnlyList可能不同的解决方案,其中一个增益(string[])铸造可以用于写访问的元素,如在mjepsen显示的答案。同样适用于IReadOnlyCollection界面友好性,尽管它的名字,在ReadOnlyCollection相似类,不支持索引的访问,它从根本上不适合制作阵列样访问)提供。


这是一种做你想做的事情的方法:

1
2
3
4
5
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;

public ReadOnlyCollection<string> Titles { get { return new List<string> {"German","Spanish","Corrects","Wrongs" }.AsReadOnly();}}

它非常类似于执行只读数组。


我相信你只能读出来。


"现在我们学院完备的缘故,所以有immutablearrays在我们的处置。这应该是真正的不可变的:

1
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new[] {"German","Spanish","Corrects","Wrongs" });

需要system.collections.immutable nuget参考

http://。/en-US /图书馆/ mt452182(V = vs.111).aspx


数组可能是那些只能在运行时。必须在编译时计算常量。尝试使用"readonly"而不是"const"。


另一种选择是,要绕过可以用只读数组修改元素的问题,可以改用静态属性。(单个元素仍然可以更改,但这些更改只能在数组的本地副本上进行。)

1
2
3
4
5
6
7
public static string[] Titles
{
    get
    {
        return new string[] {"German","Spanish","Corrects","Wrongs"};
    }
}

当然,这不会特别有效,因为每次都会创建一个新的字符串数组。