问题
Why does the following work?
class A
{
public int[,] i = { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };
static void Main(string[] args)
{
}
}
Whereas the following does not?
class A
{
public const int[,] i = { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };
static void Main(string[] args)
{
}
}
It does not allow for a const reference type other than string to be assigned anything other than null. Since it's an array (reference) it must be assigned null(?). How would it be initialized if it's constant and null?
回答1:
It's part of the language design of C#, if I remember correctly. const
is reserved for items that can have their contents deduced at-compile-time, i.e. before (during) the program is even built and then run. All arrays in C# are run-time arrays (their lengths are determined when the program runs, not before then) and thus they cannot be made into const
fields. I feel it's a limitation of C#, but that's how they decided to do it.
The reason reference types can be null is that null
is a constant value, whereas your initializer (which is made at run-time) is not. null
is built into the language, so by that logic its value is always known, all the time (and thus, usable for compile-time reference types).
EDIT:
You should be able to make a static table, though, that will be initialized the moment it is used or needed by any other code:
public static int[,] i = { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };
^ Static Keyword
You can access it like (if it's still in class A
):
A.i[0, 1]
I hope that helps you out
To learn more, look at MSDN: http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(CS0134);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5)&rd=true
EDITEDIT:
If you need to rivet the static table to the code and never let anyone change it after it's been initialized, there's the readonly
keyword for that purpose:
public static readonly int[,] i = { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };
^ Static ^Readonly Keywords
Keep in mind, it won't stop you from re-assigning things into those slots, but it's about as fixed as C# can give you, save of making a property or returning a new array every time.
回答2:
It doesn't work because that's the restriction on the const
keyword.
From MSDN:
The const keyword is used to modify a declaration of a field or local variable. It specifies that the value of the field or the local variable is constant, which means it cannot be modified.
A constant expression is an expression that can be fully evaluated at compile time. Therefore, the only possible values for constants of reference types are string and null
If you are trying to define an array that can't change, maybe you should use the readonly keyword, which restrict changes being made to a field or local variable to either declaration or in the constructor.
回答3:
Constants are evaluated at compile time. Array's are reference types, and the only way to create a reference type is to use the new
keyword (which is implicit in your code).
new
cannot be used in a constant expression, because it cannot be evaluated at compile time.
See MSDN: http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(CS0134);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5)&rd=true
来源:https://stackoverflow.com/questions/15961083/const-multi-dimensional-array-initialization