问题
Is it possible to write something similar to the following?
public const string[] Titles = { \"German\", \"Spanish\", \"Corrects\", \"Wrongs\" };
回答1:
Yes, but you need to declare it readonly instead of const:
public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
The reason is that const can only be applied to a field whose value is known at compile-time. The array initializer you've shown is not a constant expression in C#, so it produces a compiler error.
Declaring it readonly solves that problem because the value is not initialized until run-time (although it's guaranteed to have initialized before the first time that the array is used).
Depending on what it is that you ultimately want to achieve, you might also consider declaring an enum:
public enum Titles { German, Spanish, Corrects, Wrongs };
回答2:
You can declare array as readonly, but keep in mind that you can change element of readonly array.
public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Consider using enum, as Cody suggested, or IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
回答3:
You can't create a 'const' array because arrays are objects and can only be created at runtime and const entities are resolved at compile time.
What you can do instead is to declare your array as "readonly". This has the same effect as const except the value can be set at runtime. It can only be set once and it is thereafter a readonly (i.e. const) value.
回答4:
Since C# 6 you can write it like:
public static string[] Titles => new string[] { "German", "Spanish", "Corrects", "Wrongs" };
See also: C# : The New and Improved C# 6.0 (specifically the chapter "Expression Bodied Functions and Properties")
This will make a read-only static property, but it will still allow you to alter the content of the array returned, but when you call the property again, you will get the original, unaltered array again.
For clarification, this code is the same as (or actually a shorthand for):
public static string[] Titles
{
get { return new string[] { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Please note that there is a downside to this approach: A new array is actually instantiated on each and every reference, so if you are using a very large array, this might not be the most efficient solution. But if you re-use the same array (by putting it in a private attribute for instance) it will again open up the possibility to change the contents of the array.
If you want to have an immutable array (or list) you could also use:
public static IReadOnlyList<string> Titles { get; } = new string[] { "German", "Spanish", "Corrects", "Wrongs" };
But, this still has a risk for changes, as you can still cast it back to a string[] and alter the contents, as such:
((string[]) Titles)[1] = "French";
回答5:
If you declare an array behind an IReadOnlyList interface you get a constant array with constant values that is declared at runtime:
public readonly IReadOnlyList<string> Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" };
Available in .NET 4.5 and higher.
回答6:
You could take a different approach: define a constant string to represent your array and then split the string into an array when you need it, e.g.
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string[] distances = DefaultDistances.Split(',');
This approach gives you a constant which can be stored in configuration and converted to an array when needed.
回答7:
For my needs I define static array, instead of impossible const and it works:
public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
回答8:
A .NET Framework v4.5+ solution that improves on tdbeckett's answer:
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string[] { "German", "Spanish", "Corrects", "Wrongs" }
);
Note: Given that the collection is conceptually constant, it may make sense to make it static to declare it at the class level.
The above:
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 combinereadonlywith{ get; }is actually a syntax error).Alternatively, you could just omit the
{ get; }and addreadonlyto 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 anIReadOnlyList<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 theIReadOnlyCollection<T>interface, which, despite the similarity in name to classReadOnlyCollection, does not even support indexed access, making it fundamentally unsuitable for providing array-like access.)
回答9:
This is a way to do what you want:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
It is very similar to doing a readonly array.
回答10:
For the sake of completeness, now we also have ImmutableArrays at our disposal. This should be truly immutable:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new[] { "German", "Spanish", "Corrects", "Wrongs" });
Requires System.Collections.Immutable NuGet reference
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
回答11:
I believe you can only make it readonly.
回答12:
Arrays are probably one of those things that can only be evaluated at runtime. Constants must be evaluated at compile time. Try using "readonly" instead of "const".
回答13:
As an alternative, to get around the elements-can-be-modified issue with a readonly array, you can use a static property instead. (The individual elements can still be changed, but these changes will only be made on the local copy of the array.)
public static string[] Titles
{
get
{
return new string[] { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Of course, this will not be particularly efficient as a new string array is created each time.
来源:https://stackoverflow.com/questions/5142349/declare-a-const-array