常量值属性

本文关键字:属性 常量 | 更新日期: 2023-09-27 18:24:30

是否会在编译时评估常量值的非虚拟属性?(就像常数本身一样)

示例:

class Clazz
{
    const int SPEED = 5;
    public int Speed 
    {
    get { return SPEED; }
    }
}

我知道对常量SPEED的任何调用都将在编译时求值一次,但如果我从程序中的任何位置访问Clazz.Speed属性,是否也会在编译时求值

编辑:为了稍微回避这个问题,接下来的两个示例是否由编译器(而不是JIT)内联?[即在编译时评估]:

// a static / non-static method that returns a constant value
(static) int GetConstant() { return 42; }
// a static / non-static property that returns a constant value
(static) int ConstProperty { get { return 42; } }

常量值属性

通过Linqpad运行它会为getter生成以下IL:

Clazz.get_Speed:
IL_0000:  ldc.i4.5  //push integer value 5 on evaluation stack   
IL_0001:  ret 

这意味着getter在运行时被调用(而不是内联),并返回一个常数值。

假设getter在这种情况下是内联的,这意味着在不重新编译任何消耗程序集的情况下无法更改属性的实现——这将首先挫败使用属性。

否,它不会在编译时进行求值,但可能会在运行时内联。

否,编译时不会评估属性。

实际上,这是使用Property的一个好处。

以您的代码为例:

class Clazz
{
    public const int SPEED = 5;
    public int Speed 
    {
    get { return SPEED; }
    }
}

如果在另一个将在编译时评估的程序集中使用Clazz.SPEED。如果更改SPEED的值,则必须部署2个部件。

如果使用Clazz.Speed,则只需要部署Clazz所在的一个程序集。

替代方法是使用只读静态成员变量。但建议使用可灵活扩展的Property。

请阅读本书的前两项:有效C#:提高C#的50种具体方法
第1项:始终使用属性而不是可访问数据成员
第2项:首选只读而非常量