How to declare a class instance as a constant in C#?

C#.NetConstants

C# Problem Overview


I need to implement this:

static class MyStaticClass
{
    public const TimeSpan theTime = new TimeSpan(13, 0, 0);
    public static bool IsTooLate(DateTime dt)
    {
        return dt.TimeOfDay >= theTime;
    }
}

theTime is a constant (seriously :-), like π is, in my case it'd be pointless to read it from settings, for example. And I'd like it to be initialized once and never changed.

But C# doesn't seem to allow a constant to be initialized by a function (which a constructor is). How to overcome this?

C# Solutions


Solution 1 - C#

Using readonly instead of const can be initialized and not modified after that. Is that what you're looking for?

Code example:

static class MyStaticClass
{
    static readonly TimeSpan theTime;

    static MyStaticClass()
    {
        theTime = new TimeSpan(13, 0, 0);
    }
}

Solution 2 - C#

Constants have to be compile time constant, and the compiler can't evaluate your constructor at compile time. Use readonly and a static constructor.

static class MyStaticClass
{
  static MyStaticClass()
  {
     theTime = new TimeSpan(13, 0, 0);
  }

  public static readonly TimeSpan theTime;
  public static bool IsTooLate(DateTime dt)
  {
    return dt.TimeOfDay >= theTime;
  }
}

In general I prefer to initialise in the constructor rather than by direct assignment as you have control over the order of initialisation.

Solution 3 - C#

C#'s const does not have the same meaning as C++'s const. In C#, const is used to essentially define aliases to literals (and can therefore only be initialized with literals). readonly is closer to what you want, but keep in mind that it only affects the assignment operator (the object isn't really constant unless its class has immutable semantics).

Solution 4 - C#

From this link:

> Constants must be a value type (sbyte, > byte, short, ushort, int, uint, long, > ulong, char, float, double, decimal, > or bool), an enumeration, a string > literal, or a reference to null.

If you want to create an object, it must be done so as static readonly:

static class MyStaticClass
{
  public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);
  public static bool IsTooLate(DateTime dt)
  {
    return dt.TimeOfDay >= theTime;
  }
}

Solution 5 - C#

public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);

Solution 6 - C#

You can use the readonly keyword:

> 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.

Example (copied from the linked MSDN page):

> class Age > { > readonly int _year; > Age(int year) > { > _year = year; > } > void ChangeYear() > { > //_year = 1967; // Compile error if uncommented. > } > }

Solution 7 - C#

Constant represents a static member whose value can never change. This means that a constant value is defined in compile time.
With the statement:

    public const TimeSpan theTime = new TimeSpan(13, 0, 0);

Are violated two axioms of constant fields:

  • Only the C# built-in types (excluding System.Object) may be declared as const.
  • Iniatialization value must be evaluated in compile time

In the question is used the TimeSpan type, which is not built-in (predefined) Type. This means that the csc.exe compiler cannot recognize it.
If you use a built-in C# type (e.g. String) and you want to initialize the constant member with a compile time value, you still get an error: e.g.

 public const string MyNumber = SetMyString();
 private string SetMyString()
 {
  return "test";
 }

Solving the problem you can declare a member with:

static readonly

modifier if you want to declare a field only once in runtime:

public static readonly string MyNumber = SetMyString();
private static string SetMyString()
{
 return "test";
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIvanView Question on Stackoverflow
Solution 1 - C#ashelveyView Answer on Stackoverflow
Solution 2 - C#James GauntView Answer on Stackoverflow
Solution 3 - C#Etienne de MartelView Answer on Stackoverflow
Solution 4 - C#John LeeheyView Answer on Stackoverflow
Solution 5 - C#lanceView Answer on Stackoverflow
Solution 6 - C#Rudresh BhattView Answer on Stackoverflow
Solution 7 - C#George KargakisView Answer on Stackoverflow