Constants (the const keyword)
So far, we have dealt a lot with variables and as the name implies, variables can always be changed. The opposite of that is a constant, introduced in C# with the keyword const. When declaring a constant, you have to immediately assign a value to it and after that, NO changes can be made to the value of this constant. This is great when you have a value which doesn't ever change, and you want to make sure that it's not manipulated by your code, even by accident.
You will find many constants in the framework itself, e.g. in the Math class, where a constant for PI has been defined:
Console.WriteLine(Math.PI);
But of course, the interesting part is to declare some constants of our own. A constant can be defined in the scope of a method, like this:
static void Main(string[] args)
{
const int TheAnswerToLife = 42;
Console.WriteLine("The answer to life, the universe and everything: " + TheAnswerToLife);
}
However, most constants are declared on the class level, so that they can be accessed (but not changed, of course) from all methods of the class and even outside of the class, depending on the visibility. A constant will act like a static member of the class, meaning that you can access it without instantiating the class. With that in mind, let's try a full example where two constants are defined - a private and a public constant:
using System;
namespace Constants
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("The fake answer to life: " + SomeClass.TheFakeAnswerToLife);
Console.WriteLine("The real answer to life: " + SomeClass.GetAnswer());
}
}
class SomeClass
{
private const int TheAnswerToLife = 42;
public const int TheFakeAnswerToLife = 43;
public static int GetAnswer()
{
return TheAnswerToLife;
}
}
}
Notice how I define a class (SomeClass) with two constants. The first is private, so it can only be access from the class it self, but the other one is public. So, in our main program code, I access both constants differently - first directly, since the fake answer is publicly available, and secondly with the help of the GetAnswer() method.
Which types can be used as a constant?
Since constants has to be declared immediately and can't be changed later on, the value you assign to a constant has to be a constant expression and the compiler must be able to evaluate the value already at compile time. This means that numbers, boolean values and strings can be used just fine for a constant, while e.g. a DateTime object can't be used as a constant.
Since the compiler needs to know the value immediately, it also means that there are some limitations to what you can do when setting the value. For instance, these are perfect examples of what you CAN do:
const int a = 10;
const float b = a * 2.5f;
const string s1 = "Hello, world!";
const string s2 = s1 + " How are you?";
On the other hand, you can't use the result of a method call or a non-constant class member, since these are not constant expressions. Here comes a couple of examples of what you CAN'T do:
// NOT possible:
const int a = Math.Cos(4) * 2;
// Possible:
const string s1 = "Hello, world!";
// NOT possible:
const string s2 = s1.Substring(0, 6) + " Universe";
The difference lies in what the compiler can be expected to know when it reaches your code, e.g. numbers, strings and other constants, in contrast to what it has to execute to get the value for.
A constant alternative: The readonly field
If you're looking for a slightly less restrictive version of a class constant, you may want to have a look at the readonly keyword. It's not available on the method level, but it can be used on the class level, to define a field which can only be modified during declaration or the execution of the constructor method of the class. So, as soon as the object is available for use, the readonly field will have the same value forever and can't be modified by the user. Let's try it out:
class SomeClass
{
private readonly DateTime rightNow;
public readonly DateTime later = DateTime.Now.AddHours(2);
public SomeClass()
{
this.rightNow = DateTime.Now;
}
}
So, we have two readonly fields: The first is private, the second one is public (we usually have properties for that, but bear with me here). The first is declared without a value (we can do that with readonly fields, unlike with constants), while the other one is initialized immediately. You will also notice that we're using the DateTime class as the data type, and we assign a non-constant value to it. In other words, we do a lot of stuff that we can't do with constants, making readonly fields a nice alternative to constants.
Notice how I assign a value to the rightNow field in the constructor of the SomeClass class. As already mentioned, this is the last chance to assign a value to a readonly field. After that, whether you are in a method inside the defining class or outside, you will get a compile error if you try to assign a value to a readonly field.
Summary
A constant can be defined either inside the scope of a method or on the class level. It allows you to define a value which is known already at compile time and which can't be changed later on. Typical types used for constants are integers, floats, strings, and booleans. If you're looking for more flexibility, try the readonly field, as described above.