是否会在编译时评估非虚拟属性到常量值? (就像常数本身一样)
示例:
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; } }
答案 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