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

前端 未结 7 1042
逝去的感伤
逝去的感伤 2020-12-16 09:46

I need to implement this:

static class MyStaticClass
{
    public const TimeSpan theTime = new TimeSpan(13, 0, 0);
    public static bool IsTooLate(DateTime          


        
相关标签:
7条回答
  • 2020-12-16 10:10

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

    0 讨论(0)
  • 2020-12-16 10:11

    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.
        }
    }
    
    0 讨论(0)
  • 2020-12-16 10:12

    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
    {
        public static readonly TimeSpan theTime;
        static MyStaticClass
        {
            theTime = new TimeSpan(13, 0, 0)
        }
    }
    
    0 讨论(0)
  • 2020-12-16 10:22

    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";
    }
    
    0 讨论(0)
  • 2020-12-16 10:33
    public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);
    
    0 讨论(0)
  • 2020-12-16 10:34

    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.

    0 讨论(0)
提交回复
热议问题