Jai*_*Oro 421 .net c# arrays const readonly
是否可以写出类似以下的内容?
public const string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
Run Code Online (Sandbox Code Playgroud)
Cod*_*ray 639
是的,但您需要声明它readonly而不是const:
public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
Run Code Online (Sandbox Code Playgroud)
原因是const只能应用于其值在编译时已知的字段.您显示的数组初始值设定项不是C#中的常量表达式,因此会产生编译器错误.
声明它readonly解决了这个问题,因为该值在运行时才初始化(尽管它保证在第一次使用数组之前初始化).
根据您最终想要实现的目标,您可能还会考虑声明枚举:
public enum Titles { German, Spanish, Corrects, Wrongs };
Run Code Online (Sandbox Code Playgroud)
Bra*_*mir 53
您可以将数组声明为readonly,但请记住,您可以更改readonly数组的元素.
public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Run Code Online (Sandbox Code Playgroud)
考虑使用enum,如Cody建议的那样,或IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
Run Code Online (Sandbox Code Playgroud)
JAi*_*iro 45
您不能创建'const'数组,因为数组是对象,只能在运行时创建,const实体在编译时解析.
你可以做的是将你的数组声明为"只读".除了可以在运行时设置值之外,这与const具有相同的效果.它只能设置一次,然后是readonly(即const)值.
Rog*_*ill 23
这是唯一正确的答案。您目前无法执行此操作。
所有其他答案都建议使用类似于 的静态只读变量,但与常量不同。常量被硬编码到程序集中。静态只读变量可设置一次,可能是在初始化对象时。
这些有时可以互换,但并非总是如此。
编辑:我想我会把这个扔进去,因为似乎问这个问题的人对数组有点模糊。当您声明一个数组时,它是一个指向包含该数组的内存段的指针。它非常简单,它只是一个地址,没有复杂的逻辑控制它是否可读或可写。它给了你一个指针,你可以用它做任何你想做的事。
这就是为什么制作不可变数组有点棘手的部分原因。您可以编写一个包装数组的类,并且只允许通过返回副本来读取它,但它实际上不再只是一个数组。
有些人建议使用 static 或 readonly 来模拟如果可以创建 const 数组时会看到的行为。这些有一些副作用,对于普通读者来说可能并不明显。
要真正获得 const 数组,需要对 C# 和 MSIL 底层代码进行更新,以允许从数组中读取,但不允许写入。
mje*_*son 12
从C#6开始,你可以这样写:
public static string[] Titles => new string[] { "German", "Spanish", "Corrects", "Wrongs" };
Run Code Online (Sandbox Code Playgroud)
另请参阅:C#:新增和改进的C#6.0(特别是"表达身体功能和属性"一章)
这将创建一个只读的静态属性,但它仍然允许您更改返回的数组的内容,但是当您再次调用该属性时,您将再次获得原始的,未改变的数组.
为了澄清,此代码与(或实际上是简写)相同:
public static string[] Titles
{
get { return new string[] { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Run Code Online (Sandbox Code Playgroud)
请注意,这种方法有一个缺点:新的数组实际上是在每个引用上实例化的,所以如果你使用的是非常大的数组,这可能不是最有效的解决方案.但是如果你重新使用相同的数组(例如通过将它放在私有属性中),它将再次打开更改数组内容的可能性.
如果你想拥有一个不可变的数组(或列表),你也可以使用:
public static IReadOnlyList<string> Titles { get; } = new string[] { "German", "Spanish", "Corrects", "Wrongs" };
Run Code Online (Sandbox Code Playgroud)
但是,这仍然存在更改的风险,因为您仍然可以将其强制转换为字符串[]并更改内容,如下所示:
((string[]) Titles)[1] = "French";
Run Code Online (Sandbox Code Playgroud)
小智 8
为了完整起见,现在我们还可以使用 ImmutableArrays。这应该是真正不可变的:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new[] { "German", "Spanish", "Corrects", "Wrongs" });
Run Code Online (Sandbox Code Playgroud)
需要 System.Collections.Immutable NuGet 参考
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
您可以采用不同的方法:定义一个常量字符串来表示您的数组,然后在需要时将字符串拆分为数组,例如
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string[] distances = DefaultDistances.Split(',');
Run Code Online (Sandbox Code Playgroud)
这种方法为您提供了一个常量,可以存储在配置中并在需要时转换为数组.
阿拉斯泰尔
如果在IReadOnlyList接口后面声明一个数组,则会获得一个常量数组,该数组具有在运行时声明的常量值:
public readonly IReadOnlyList<string> Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" };
Run Code Online (Sandbox Code Playgroud)
适用于.NET 4.5及更高版本.
为了我的需要,我定义static数组,而不是不可能const,它的工作原理:
public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
这是一种做你想做的事情的方法:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
Run Code Online (Sandbox Code Playgroud)
它与做一个只读数组非常相似。
一个.NET框架V4.5 +解决方案是提高了tdbeckett的回答:
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string[] { "German", "Spanish", "Corrects", "Wrongs" }
);
Run Code Online (Sandbox Code Playgroud)
注意:鉴于集合在概念上是恒定的,因此static使其在类级别进行声明可能很有意义。
以上:
使用数组一次初始化属性的隐式后备字段。
注意{ get; }-即,仅声明属性getter-是使属性本身隐式只读的原因(尝试readonly与之合并{ get; }实际上是语法错误)。
或者,您可以省略{ get; }和添加readonly以创建字段而不是属性,如在问题中所示,但是将公共数据成员公开为属性而不是字段是一种良好的习惯。
创建一个类似于数组的结构(允许索引访问),该结构真正且健壮地为只读(概念上是常量,一旦创建),就以下方面而言:
IReadOnlyList<T>解决方案,其中一个(string[])投可以用来获得对要素的写入权限,如图mjepsen的帮助的解答。IReadOnlyCollection<T> 接口,其中,尽管在名称相似to class ReadOnlyCollection,甚至不支持索引访问,这使其从根本上不适合提供类似数组的访问。)| 归档时间: |
|
| 查看次数: |
354839 次 |
| 最近记录: |