Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't structs be declared as const? [duplicate]

They are immutable value types on the stack. What keeps me from having them a const?

References:

  • http://msdn.microsoft.com/en-us/library/ah19swz4(v=vs.71).aspx
  • http://msdn.microsoft.com/en-us/library/aa664465(v=vs.71).aspx
  • http://msdn.microsoft.com/en-us/library/aa288471(v=vs.71).aspx
like image 905
Lazlo Avatar asked Jan 04 '11 05:01

Lazlo


People also ask

Can a struct be const?

'const' as the word constant itself indicates means unmodifiable. This can be applied to variable of any data type. struct being a user defined data type, it applies to the the variables of any struct as well. Once initialized, the value of the const variables cannot be modified.

Are structs copied by value?

We can now modify every property of those variables without affecting the other object, because the Dog struct contains basic types, which are copied by value.

Can we use const inside structure?

No, using const in such a way is not a good idea. By declaring your structure fields as const , you are declaring an intention that those fields will never change their value.

Can class inherit from struct C#?

It is not possible to inherit from a struct and a struct can't derive from any class. Similar to other types in . NET, struct is also derived from the class System.


4 Answers

Because the value type constructor might do anything -- for example, switch logic based on the time of day. Constant value types makes sense intellectually, but it simply cannot work on custom value types in practice due to the flexibility of constructors to do whatever they please. (Remember that constants are evaluated at compile time, which means your constructor would have to be run at compile time.)

like image 198
cdhowie Avatar answered Oct 19 '22 18:10

cdhowie


Const in C# means it can be determined at compile time, which is why only very primitive types such as int and string can be a const.

If you are coming from a C background, the readonly keyword might better suit you.

like image 21
vcsjones Avatar answered Oct 19 '22 19:10

vcsjones


For the C# compiler to produce a const value of a structure type it must know what values should go in all its fields. The C# compiler intrinsically knows how to initialize the fields of certain types like Decimal, but for most value types it has no such knowledge.

It would be possible for a compiler to provide a means of declaring constant values of a structure type in contexts where all of the struct fields were exposed. If a structure's fields were private, constants of that type could then be declared only within the structure; if the fields were internal, constants could be declared anywhere within the assembly; if public, they could be declared anywhere.

Although I would like to see such a feature, I do not expect any mainstream .net languages to implement it. Named constants of types the compiler inherently knows about can participate in other constant expressions, whereas static readonly variables cannot. If NumRows is a constant equal to 4, an expression like Arr[3*NumRows+7] can be replaced by Arr[19] even if NumRows is defined in an outside assembly. This gives such constants a substantial advantage over static readonly variables. If, however, a constant is of a type that a compiler does not intrinsically recognize, it would have very limited ability to participate in any constant expressions, effectively negating the advantage of its being a constant in the first place. If a value-type constant had an exposed field, it would be possible for a compiler to use the value of that field as a constant, but since the creators of .net languages are philosophically opposed to structures with exposed fields, I would not expect them to allow such usage even if they could.

There would be some potential use cases for favoring constants over static readonly variables, but many such cases can be handled acceptably using existing types. For example, a library might expose a const Int64 to encode information about its version, and use that value as a default parameter value for a GetLinkedVersionInfo method. The value in question would get "baked into" the calling code when it was compiled, thus allowing the method to report what version of the library the caller was linked with, and possibly identify whether there are any compatibility problems with the version it's running.

like image 23
supercat Avatar answered Oct 19 '22 18:10

supercat


I just tested the readonly keyword with a simple mutable struct:

struct Test
{
   public int value;

   public void setInt(int val)
   {
      value = val;
   }
}

static class Program
{
   public static readonly Test t = new Test();

   static void Main()
   {
      Console.WriteLine(t.value); // Outputs "0"
      t.setInt(10);
      //t.value = 10;  //Illegal, will not let you assign field of a static struct
      Console.WriteLine(t.value); // Still outputs "0"
   }
}

Even though a readonly struct isn't technicly a compile time constant, the runtime wont let it change. Even stepping threw the setInt() method it looks like value changes, but does not show the change in Main.

I guess the struct itself is placed in "readonly" memory, disallowing them to change. Unlike a class, which just keeps the pointer constant, allowing the class fields themselves to change as they wish.

So it appears static readonly is effectivly a const, even for mutable structs.

like image 36
Cemafor Avatar answered Oct 19 '22 20:10

Cemafor