Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 定值属性_C#_Constants - Fatal编程技术网

C# 定值属性

C# 定值属性,c#,constants,C#,Constants,是否在编译时对常量值的非虚拟属性求值?就像常数本身一样 例如: class Clazz { const int SPEED = 5; public int Speed { get { return SPEED; } } } 我知道任何对恒定速度的调用都会在编译时计算一次,但是如果我从程序中的任何地方访问Clazz.SPEED属性,那么它也会在编译时计算吗 编辑:为了回答这个问题,接下来的两个示例是由编译器内联的,而不是由JIT内联的吗?[即,在编译时

是否在编译时对常量值的非虚拟属性求值?就像常数本身一样

例如:

class Clazz
{
    const int SPEED = 5;

    public int Speed 
    {
    get { return 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; } }

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

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

不,属性不会在编译时求值

实际上,这是使用财产的一个好处

以您的代码为例:

class Clazz
{
    public const int SPEED = 5;

    public int Speed 
    {
    get { return SPEED; }
    }
}
如果在另一个程序集中使用Clazz.SPEED,将在编译时对其进行计算。如果更改速度值,则必须部署2个程序集

如果使用Clazz.Speed,则只需部署该Clazz驻留的一个程序集

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

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

否,编译时将不计算属性

实际上,这是使用财产的一个好处

以您的代码为例:

class Clazz
{
    public const int SPEED = 5;

    public int Speed 
    {
    get { return SPEED; }
    }
}
如果在另一个程序集中使用Clazz.SPEED,将在编译时对其进行计算。如果更改速度值,则必须部署2个程序集

如果使用Clazz.Speed,则只需部署该Clazz驻留的一个程序集

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

请阅读本书的前两项:有效C:50提高C的具体方法 Item1:始终使用属性而不是可访问的数据成员
第2项:宁愿只读也不要常量通过Linqpad运行此命令会为getter生成以下IL:

Clazz.get_Speed:
IL_0000:  ldc.i4.5  //push integer value 5 on evaluation stack   
IL_0001:  ret 
这意味着getter在运行时被调用,而不是内联的,并返回一个常量值


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

通过Linqpad运行此操作将为getter生成以下IL:

Clazz.get_Speed:
IL_0000:  ldc.i4.5  //push integer value 5 on evaluation stack   
IL_0001:  ret 
这意味着getter在运行时被调用,而不是内联的,并返回一个常量值


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

您试图实现什么?你有什么问题,这很重要?@M.Babcock说实话,这并没有解决任何具体的问题,只是我想到的一个想法。当我在网上找不到这个问题的答案时,我感到很惊讶。这可能更适合这种格式。理论上,编译器中发生了什么,以及为什么类型问题稍微超出了SO的范围。您试图实现什么?你有什么问题,这很重要?@M.Babcock说实话,这并没有解决任何具体的问题,只是我想到的一个想法。当我在网上找不到这个问题的答案时,我感到很惊讶。这可能更适合这种格式。理论上,编译器中发生了什么,以及为什么类型问题稍微超出了SO的范围。是什么阻止编译器内联返回常量值的非虚拟方法?如果它在另一个程序集中,则可以在不重新编译的情况下切换该程序集,行为必须改变。@svick有什么办法可以强制编译器内联吗?@acid,是的,直接使用const字段。如果不这样做,就是告诉编译器您不想内联该值。是什么阻止编译器内联返回常量值的非虚拟方法?如果它在另一个程序集中,则可以在不重新编译的情况下切换该程序集,行为必须改变。@svick有什么办法可以强制编译器内联吗?@acid,是的,直接使用const字段。如果不这样做,则告诉编译器您不想内联该值。