'Static readonly' vs. 'const'

前端 未结 18 2528
旧巷少年郎
旧巷少年郎 2020-11-22 04:07

I\'ve read around about const and static readonly fields. We have some classes which contain only constant values. They are used for various things

18条回答
  •  有刺的猬
    2020-11-22 04:53

    This is just a supplement to the other answers. I will not repeat them (now four years later).

    There are situations where a const and a non-const have different semantics. For example:

    const int y = 42;
    
    static void Main()
    {
      short x = 42;
      Console.WriteLine(x.Equals(y));
    }
    

    prints out True, whereas:

    static readonly int y = 42;
    
    static void Main()
    {
      short x = 42;
      Console.WriteLine(x.Equals(y));
    }
    

    writes False.

    The reason is that the method x.Equals has two overloads, one that takes in a short (System.Int16) and one that takes an object (System.Object). Now the question is whether one or both apply with my y argument.

    When y is a compile-time constant (literal), the const case, it becomes important that there does exist an implicit conversion from int to short provided that the int is a constant, and provided that the C# compiler verifies that its value is within the range of a short (which 42 is). See Implicit constant expression conversions in the C# Language Specification. So both overloads have to be considered. The overload Equals(short) is preferred (any short is an object, but not all object are short). So y is converted to short, and that overload is used. Then Equals compares two short of identical value, and that gives true.

    When y is not a constant, no implicit conversion from int to short exists. That's because in general an int may be too huge to fit into a short. (An explicit conversion does exist, but I didn't say Equals((short)y), so that's not relevant.) We see that only one overload applies, the Equals(object) one. So y is boxed to object. Then Equals is going to compare a System.Int16 to a System.Int32, and since the run-time types do not even agree, that will yield false.

    We conclude that in some (rare) cases, changing a const type member to a static readonly field (or the other way, when that is possible) can change the behavior of the program.

提交回复
热议问题