3

In C#, you can define a const string, but not an array as arrays are objects. It is to my understanding that strings are in fact objects as they are reference objects passed by value just like arrays.

So how is it that we can do this:

const string NewLine = "\r\n";

but not this:

const byte[] AesSwapBytes = new byte[] { ... };

Is it because we can't change individual characters on strings (NewLine[0] = '\n'), but can on arrays (arr[0] = i)?

Cole Tobin
  • 9,206
  • 15
  • 49
  • 74
  • If you only need a proper c# Array that cannot be reassigned, using `static readonly` might be sufficient. – StoriKnow Aug 19 '12 at 03:45
  • 3
    You can declare strings as constants as strings can be created and represented using literals (like any other type that can be used as literals or in attributes). You can't define a literal array, you have to instantiate one. – Jeff Mercado Aug 19 '12 at 03:47
  • you can also declare what they call dynamic array for example string[] dynamicArray = {}; then if you need to size it dynamically this will work for you without having to initialize it to a particular size.. – MethodMan Aug 19 '12 at 03:49
  • 2
    @Sam You can reassign values on a readonly array however. – Cole Tobin Aug 19 '12 at 03:51
  • 2
    @DJKRAZE: There's no such thing as a dynamic array, not in C# (or .NET for that matter). That's just a collection initializer that happens to be empty. The array that is created in that case is a `0` length string array. No you cannot dynamically increase the size, it's fixed. You can however initialize with as many values as you could type in. But all you're getting is some compiler magic being performed generating the instructions to create the n-length array and setting each of the n-values in their respective places in the array. – Jeff Mercado Aug 19 '12 at 04:04
  • Jeff yes there is.. I can send you code samples to prove it.. and I have used it many times.. would you like to see a working example..? – MethodMan Aug 19 '12 at 04:05
  • 1
    @DJKRAZE, I agree with Jeff. The array creation from your comment above (`string[] dynamicArray = {}`) wouldn't create a "dynamic array" at all, it would just create a fixed-size, empty array. Once the array is created, there's no way to change its size. All you can do is create another array and copy the data. – Thomas Levesque Aug 19 '12 at 04:09
  • I will not debate this ..I could however share an example and would love for someone to explain to me how this is possible then if you claim that it's not possible..?? what about http://msdn.microsoft.com/en-us/library/system.collections.arraylist.aspx or http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx – MethodMan Aug 19 '12 at 04:11
  • have a good weeked Thomas and Jeff.. I appreciate your positive feedback – MethodMan Aug 19 '12 at 04:15
  • @DJKRAZE Those are not arrays, they may use arrays internally, but there is not a singular static array that exist inside the object. You can check for your self using [ILSpy](http://wiki.sharpdevelop.net/ILSpy.ashx) Specifically look at the code in ArrayList for `Add(object)`, which calls `EnsureCapacity()`, which calls the setter for `this.Capacity` which contains `object[] array = new object[value]; if (this._size > 0) { Array.Copy(this._items, 0, array, 0, this._size); } this._items = array;`. So it is calling `new object[value]` every time you add more items than it it's capacity. – Scott Chamberlain Aug 19 '12 at 05:06
  • @ScottChamberlain funny it doesn't use Array.Resize – Cole Tobin Aug 19 '12 at 16:07
  • possible duplicate of [Declare a Const Array](http://stackoverflow.com/questions/5142349/declare-a-const-array) – Cole Tobin Aug 21 '13 at 15:00

4 Answers4

2

Whether or not you can make a variable has nothing to do with whether it's an object, or a struct. What is required to make a variable const is that the right hand size of the assignment must be a compile time literal. There are only a handful of types that have compile time literals. string is one, as is int, double, and the other numeric types. As was mentioned in another answer, null is a compile time literal, so if you really wanted to you could assign any nullable type to be const and assign null to it (not that it would really be useful). If C# were to add compile time literals (other than null) that resulted in arrays then you could create a meaningful const array. Until then, you'll be stuck using some other mechanisms to do what you want.

Servy
  • 202,030
  • 26
  • 332
  • 449
1

According to this MSDN post, one can define a readonly array in C#. C# specifically does not let you declare arrays as constant because the assignment expression is not constant.

public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

However, the first comment details that this is sort of useless anyway, since

you can't reassign the array, but you can replace individual values.

More information on Stack Overflow here

Community
  • 1
  • 1
David B
  • 2,688
  • 18
  • 25
  • It's not useless, since it's often important to know whether an array-type field will always point to *the same* array instance. Among other things, wrapping an array in a `ReadOnlyCollection` will yield a "live" read-only view if the variable always points to the same array, but a broken one if the field later refers to a different array. People who don't understand the distinction between holding an object and holding a reference may be confused by a `readonly` designator, but those who do understand the distinction will recognize its significance. – supercat Oct 10 '12 at 23:37
  • @supercat I was referring to the fact that the array doesn't act like what we would normally expect to be `readonly`, since it is, in fact, mutable. – David B Oct 11 '12 at 22:05
  • It's unfortunate that the C# syntax `readonly int[] Foo` makes it look as though `Foo` is a read-only array of integers, as opposed to the vb-style `ReadOnly Foo As Integer()`, which looks more like a declaration of a read-only reference to an array of integers, but someone who understands C# and .net should understand what is and is not promised by the declaration; anyone who cannot understand that will likely have other major problems with understanding the differences between `Array1 = Array2`, `Array1 = (int[])Array2.Clone()`, and `Array.Copy(Array1, Array2, Array1.Length);`. – supercat Oct 11 '12 at 22:27
1

You can in fact declare an array constant, using the const keyword, as long as the initializer is a compile-time constant.

const byte[] Nothing = null;

As a general rule, for reference types, only null is a compile-time constant.

.NET makes a special exception to also allow string literals.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

The problem with an array declared as readonly is that even though the field is readonly (you can't make it reference another array), the content of the array itself can be changed.

If you need an "immutable array" where you can't change the content, the answer is: don't use an array. Arrays are mutable, and there is nothing you can do about it.

A possible workaround is to use a readonly collection:

static readonly IList<byte> AesSwapBytes =
    new ReadOnlyCollection<byte>(new byte[] { ... });

If you need to use it as an array, just call the ToArray extension method on it. It will return an array with a copy of the data, not the original array; so if you modify the result of ToArray, it won't affect the original collection.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758