是否可以写出类似于下面的内容?
public const string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
是否可以写出类似于下面的内容?
public const string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
当前回答
你可以采用一种不同的方法:定义一个常量字符串来表示你的数组,然后在你需要它的时候把字符串分割成一个数组。
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string[] distances = DefaultDistances.Split(',');
这种方法为您提供了一个可以存储在配置中并在需要时转换为数组的常量。
其他回答
这是一种做你想做的事情的方法:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
它非常类似于做一个只读数组。
是的,但是你需要声明它为readonly而不是const:
public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
原因是const只能应用于编译时已知值的字段。您所展示的数组初始化器不是c#中的常量表达式,因此会产生编译器错误。
声明它为readonly可以解决这个问题,因为值直到运行时才初始化(尽管可以保证在第一次使用数组之前已经初始化)。
根据你最终想要实现的目标,你也可以考虑声明一个枚举:
public enum Titles { German, Spanish, Corrects, Wrongs };
.NET Framework v4.5+解决方案,改进了tdbeckett的答案:
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string[] { "German", "Spanish", "Corrects", "Wrongs" }
);
注意:假定集合在概念上是常量,在类级别声明它时将其设置为静态可能是有意义的。
上面的:
Initializes the property's implicit backing field once with the array. Note that { get; } - i.e., declaring only a property getter - is what makes the property itself implicitly read-only (trying to combine readonly with { get; } is actually a syntax error). Alternatively, you could just omit the { get; } and add readonly to create a field instead of a property, as in the question, but exposing public data members as properties rather than fields is a good habit to form. Creates an array-like structure (allowing indexed access) that is truly and robustly read-only (conceptually constant, once created), both with respect to: preventing modification of the collection as a whole (such as by removing or adding elements, or by assigning a new collection to the variable). preventing modification of individual elements. (Even indirect modification isn't possible - unlike with an IReadOnlyList<T> solution, where a (string[]) cast can be used to gain write access to the elements, as shown in mjepsen's helpful answer. The same vulnerability applies to the IReadOnlyCollection<T> interface, which, despite the similarity in name to class ReadOnlyCollection, does not even support indexed access, making it fundamentally unsuitable for providing array-like access.)
数组可能是一种只能在这里求值的东西 运行时。常量必须在编译时求值。尝试使用"readonly" 而不是"const"。
从c# 6开始,你可以这样写:
public static string[] Titles => new string[] { "German", "Spanish", "Corrects", "Wrongs" };
参见:c#:新的和改进的c# 6.0(特别是“表达式体函数和属性”一章)
这将使一个只读的静态属性,但它仍然允许您更改返回的数组的内容,但当您再次调用该属性时,您将再次获得原始的、未更改的数组。
为了澄清,这段代码与(或实际上是缩写)相同:
public static string[] Titles
{
get { return new string[] { "German", "Spanish", "Corrects", "Wrongs" }; }
}
请注意,这种方法有一个缺点:每个引用实际上都会实例化一个新数组,因此如果您使用的是一个非常大的数组,这可能不是最有效的解决方案。 但是如果你重复使用相同的数组(例如把它放在一个私有属性中),它将再次打开改变数组内容的可能性。
如果你想要一个不可变数组(或列表),你也可以使用:
public static IReadOnlyList<string> Titles { get; } = new string[] { "German", "Spanish", "Corrects", "Wrongs" };
但是,这仍然有更改的风险,因为你仍然可以将其转换回字符串[]并更改内容,如下所示:
((string[]) Titles)[1] = "French";