常量值属性

时间:2012-02-15 01:17:59

标签: c# constants

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

示例:

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; } }

3 个答案:

答案 0 :(得分:3)

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

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

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

假设在这种情况下,如果getter将被内联,这意味着无需重新编译任何消耗程序集就无法更改属性的实现 - 这将首先使用属性失败。

答案 1 :(得分:2)

不,它不会在编译时进行评估,但可能会在运行时进行内联。

答案 2 :(得分:1)

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

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

以您的代码为例:

class Clazz
{
    public const int SPEED = 5;

    public int Speed 
    {
    get { return SPEED; }
    }
}

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

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

替代方案是使用只读静态成员变量。但建议物业可以灵活扩展。

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