Const multi-dimensional array initialization

江枫思渺然 提交于 2021-02-18 09:59:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!