21

I have a question. Lately I have caught myself using 3 different lines of code which upon closer inspection looks and feels the same.

public static class constant
{
    public static readonly int val1 = 5;
    public const int val2 = 5;
    public static int val3 { get { return 5; } }
}

my question is, are they the same and should one be used over another? if so. When?

also as a extra question in visual studio why are they all represented differently in intellisense?

enter image description here

0

7 Answers 7

10

The member declared as readonly gives the possibility to be changed in the (static) constructor of the class, while the const member cannot be changed at runtime.

Declaring a field as const makes it automatically static, quoting from §10.3.7:

When a field, method, property, event, operator, or constructor declaration includes a static modifier, it declares a static member. In addition, a constant or type declaration implicitly declares a static member.

The third is just a read-only property which happens to always return 5.

You should never use such a property and prefer const members where possible in order to allow the compiler and/or the jitter to perform their optimizations and to help other people reading your code (that property is kind of a WTF to me). The static readonly member has to be used if it is required a constant value initialized during the program start-up (like, for example, the number of cores of a machine).

This is a great example from the C# specs (§10.5.2.1):

A static readonly field is useful when a symbolic name for a constant value is desired, but when the type of the value is not permitted in a const declaration, or when the value cannot be computed at compile-time. In the example

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue = new Color(0, 0, 255);
    private byte red, green, blue;
    public Color(byte r, byte g, byte b) {
        red = r;
        green = g;
        blue = b;
    }
}

the Black, White, Red, Green, and Blue members cannot be declared as const members because their values cannot be computed at compile-time. However, declaring them static readonly instead has much the same effect.

And yet another difference (§10.5.2.2):

Constants and readonly fields have different binary versioning semantics. When an expression references a constant, the value of the constant is obtained at compile-time, but when an expression references a readonly field, the value of the field is not obtained until run-time.

So, summing it up, they are very different even if at a first glance they might look similar and you should use the one which best suits your intent.

0
1

Hi you will find the answer for your questions in this post:

Static readonly vs const

You can also check the IL code and trying to compare the result by your self.

1
  • 2
    it don't explain the visual studio icons and the get example Commented Sep 2, 2013 at 18:43
0

You should use constant fields whenever you can - but this works only for primitive types.

When you need a custom type (say your own class or struct), you should use public static property.

Public fields is used only in structs, and I cannot recall any case where I saw any public static readonly field.

2
  • string.Empty is a public static readonly field.
    – Fede
    Commented Sep 2, 2013 at 18:29
  • Type.Missing Type.EmptyTypes and so many are examples of public static readonly fields Commented Sep 2, 2013 at 18:45
0

Static readonly can be assigned at constroctor whereas the const cannot. Also, the getter does not have to return a constant value, the value van be a private member, which can be changed in another part of the class, or be a calculated value.

From readonly (C# Reference)

The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants as in the following example:

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;

The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.

From const (C# Reference)

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.

Also, the are different in the intellisense as they are different compile time objects

1
  • 1
    This does not answer the question.
    – AgentFire
    Commented Sep 2, 2013 at 18:29
0

Const is an expression evaluated at compile time. The compiler may embed the value directly in every place its used. Static read only will only be evaluated at runtime, and is useful if you think the value might be changed later as assemblies compiled against yours won't have the static read only value embedded, which can happen with a const. Note some values like DateTime.Now can't be stored in a const because its the evaluation of a property which must be done at runtime. You can use static read only and it will be similar to a const but it will capture the value at runtime.

The final one is a property which can do much more than just return a value. It might be the result of a web service call or complex calculation. Note that the code in the property might get inlined by the compiler.

Which one you use depends on the semantics you want.

0

when you use const or readonly in your field definitions. The const qualifier can be used with primitive data types, and strings only. When used, the value assigned to a const field is inserted directly in all its references in the generated IL code. This is true about other assemblies too. Other assemblies that refer to that const field are compiled as if they have used directly the value itself. Readonly fields are run-time constants. They occupy some place in memory, and references to them are resolved in run-time, as if we have referred to an ordinary variable. Actually they are variables that resemble constants.

const:

As a general rule, try to avoid constants, because the value is not only hard-coded into the assembly in which they are declared, but also into any assemblies that reference the constant value as well. This can create some real strange issues.

  • Can't be static.
  • Value is evaluated at compile time.
  • Initiailized at declaration only.

readonly:

  • Can be either instance-level or static.
  • Value is evaluated at run time.
  • Can be initialized in declaration or by code in the constructor.
0

I just explain your first question.

Const; the members should be given initial values ​​at compile time and then they can not be changed. Static readonly; members' values​​ do not have to be assigned to be initialized, then be assigned. Following the appointment can not be changed once.

Static readonly members can be accessed from within the class to which they belong and the value can be assigned. The first assignment of a value to be assigned the value of the members must be done or static constructor should be made in a transaction.

Not the answer you're looking for? Browse other questions tagged or ask your own question.