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".
I believe you can only make it readonly.
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.
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";
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.
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.
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();
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 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:
IReadOnlyList<T>
solution, where a (string[])
cast can be used to gain write access to the elements, as shown in mjepsen's helpful answer.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.)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.
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
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.
Best alternative:
public static readonly byte[] ZeroHash = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
This is the only correct answer. You cannot currently do this.
All the other answers are suggesting using static read-only variables which are similar to, but not the same as a constant. A constant is hard coded into the assembly. A static read only variable is settable once, probably as an object is is initialized.
These are sometimes interchangeable, but not always.
For my needs I define static
array, instead of impossible const
and it works:
public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
Source: Stackoverflow.com