Why aren't arrays of constants equivalent to constant expressions?

J

JJ Feminella

This statement is legal C#:

public const string day = "Sunday";

but this statement is not:

public const string[] days = new string[] { "Sun", "Mon", "Tue" };

The C# Programmer's Reference specifies that 'the only valid values of a constant declarator [involve] constant expressions'. A constant expression is defined as 'an expression that can be fully evaluated at compile-time ... Therefore, the only possible values for constants of reference types are string and null.'

In other words, constant arrays of any otherwise constant type are not legal C#. I understand that this is the case because string[] is really of type System.Array, which is an object (also a dead giveaway since we used the new operator). Fine. I'll get the next best thing and use static readonly in place of where I'd like to use const. The statement becomes:

public static readonly string[] days = new string[] { "Sun", "Mon", "Tue" };

and the compiler's happy.

But now if I run FxCop on an assembly containing this statement, it gets mad at me:

'... Fields that are arrays should not be readonly'
'Make the array 'const' to truly protect its contents.'

What the heck? Am I missing something here? How do you declare a constant array? Any help would be greatly appreciated. Thanks.
 
1

100

Hi JJ,
I belive this is FxCop mistake. FxCop is right in one, though - declaring an array as readonly doesn't protect your array of changing its items. Consider this

I always can do

someobj.days[0] = "Fri";

what you protect against is that I cannot make
someobj.days = new string[]{"Wed", "Thu", "Fri"}

So *constant* is not fully covered by *readonly*

But this is the best you can do about the arrays at the moment, I believe. FxCop gives you wrong advice.

If you want more constantness you can inherit your own class from CollectionBase let say and make it readonly strongly-typed collection. Then make an object of this collection visible to the rest of the classes via readonly data member or get-only property.

HTH
B\rgds
100


This statement is legal C#:

public const string day = "Sunday";

but this statement is not:

public const string[] days = new string[] { "Sun", "Mon", "Tue" };

The C# Programmer's Reference specifies that 'the only valid values of a constant declarator [involve] constant expressions'. A constant expression is defined as 'an expression that can be fully evaluated at compile-time ... Therefore, the only possible values for constants of reference types are string and null.'

In other words, constant arrays of any otherwise constant type are not legal C#. I understand that this is the case because string[] is really of type System.Array, which is an object (also a dead giveaway since we used the new operator). Fine. I'll get the next best thing and use static readonly in place of where I'd like to use const. The statement becomes:

public static readonly string[] days = new string[] { "Sun", "Mon", "Tue" };

and the compiler's happy.

But now if I run FxCop on an assembly containing this statement, it gets mad at me:

'... Fields that are arrays should not be readonly'
'Make the array 'const' to truly protect its contents.'

What the heck? Am I missing something here? How do you declare a constant array? Any help would be greatly appreciated. Thanks.
 
R

Rafael M. Munoz [MSFT]

for (e-mail address removed)

Sorry for the injection of this post but this I am trying to get a hold of
(e-mail address removed) to discuss the MVP program and was hoping they could email me at
(e-mail address removed). Thanks

--
Rafael M. Munoz
Microsoft PSS Global Community
MVP Lead - .NET / VB / VC# / VJ#

This posting is provided 'AS IS' with no warranties, and confers no rights.
Microsoft Strategic Technology Protection Program for information -
http://www.microsoft.com/security.

---------------------
Hi JJ,
I belive this is FxCop mistake. FxCop is right in one, though - declaring an
array as readonly doesn't protect your array of changing its items. Consider
this

I always can do

someobj.days[0] = "Fri";

what you protect against is that I cannot make
someobj.days = new string[]{"Wed", "Thu", "Fri"}

So *constant* is not fully covered by *readonly*

But this is the best you can do about the arrays at the moment, I believe.
FxCop gives you wrong advice.

If you want more constantness you can inherit your own class from
CollectionBase let say and make it readonly strongly-typed collection. Then
make an object of this collection visible to the rest of the classes via
readonly data member or get-only property.

HTH
B\rgds
100


This statement is legal C#:

public const string day = "Sunday";

but this statement is not:

public const string[] days = new string[] { "Sun", "Mon", "Tue" };

The C# Programmer's Reference specifies that 'the only valid values of a
constant declarator [involve] constant expressions'. A constant expression
is defined as 'an expression that can be fully evaluated at compile-time ...
Therefore, the only possible values for constants of reference types are
string and null.'

In other words, constant arrays of any otherwise constant type are not legal
C#. I understand that this is the case because string[] is really of type
System.Array, which is an object (also a dead giveaway since we used the new
operator). Fine. I'll get the next best thing and use static readonly in
place of where I'd like to use const. The statement becomes:

public static readonly string[] days = new string[] { "Sun", "Mon",
"Tue" };

and the compiler's happy.

But now if I run FxCop on an assembly containing this statement, it gets mad
at me:

'... Fields that are arrays should not be readonly'
'Make the array 'const' to truly protect its contents.'

What the heck? Am I missing something here? How do you declare a constant
array? Any help would be greatly appreciated. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top