Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.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# - Fatal编程技术网

C# 如何强制运行时常量成为编译时常量?

C# 如何强制运行时常量成为编译时常量?,c#,C#,所以我在做一个基于化学的项目,遇到了这个棘手的问题。我有一堆函数在做化学类型的计算,我想把阿伏伽德罗斯数作为一个函数的默认参数来传递。让我来谈谈代码: class Constants { //must be readonly to b/c Math.Pow is calculated at run-time public static double readonly avogadrosNum = 6.022*Math.Pow(10,-22); } class chemCal

所以我在做一个基于化学的项目,遇到了这个棘手的问题。我有一堆函数在做化学类型的计算,我想把阿伏伽德罗斯数作为一个函数的默认参数来传递。让我来谈谈代码:

class Constants 
{
    //must be readonly to b/c Math.Pow is calculated at run-time
    public static double readonly avogadrosNum = 6.022*Math.Pow(10,-22);
} 

class chemCalculations
{   //getting default parameter must be a compile-time constant
    public double genericCalc(double avogadrosNum = Constants.avogadrosNum);  
}

编辑:不知道指数格式,谢谢各位

只需将阿伏伽德罗斯数定义为科学符号:

class Constants 
{
    public double const avogadrosNum = 6.022e-22;
} 

您可以按指数格式执行:
6.022E-22

一般来说,您不能。就编译器而言,任何涉及方法调用的内容都不会是编译时常量

您可以使用科学符号表示
double
文字:

public const double AvogadrosNumber = 6.022e-22;
因此,在这种特定情况下,您可以编写它,而不会丢失可读性

在其他设置中,只要类型是基元类型或decimal,就可以将常量作为文本写出,并使用注释解释如何获得它。例如:

// Math.Sqrt(Math.PI)
public const double SquareRootOfPi = 1.7724538509055159;
// This is fine
public const double PiSquared = Math.PI * Math.PI;

// This is invalid
public const double PiSquared = Math.Pow(Math.PI, 2);
注意,即使方法调用不能在常量表达式中使用,其他运算符也可以。例如:

// Math.Sqrt(Math.PI)
public const double SquareRootOfPi = 1.7724538509055159;
// This is fine
public const double PiSquared = Math.PI * Math.PI;

// This is invalid
public const double PiSquared = Math.Pow(Math.PI, 2);

有关常量表达式中允许的内容的更多详细信息,请参见C#5规范第7.19节。

对于编译时常量,您需要使用
const
关键字。但是,要使用它,表达式本身也需要是编译时常量,正如您所注意到的:您不能使用诸如
Math.Pow
之类的函数

class Constants
{
    public const double avogadrosNum = 6.022E-22;
}
如果不能或不想将常量重新编译为编译时常量,则不能在编译时上下文中使用它,但可以通过重载来解决此问题,以便运行时值可以用作某种默认参数:

class chemCalculations
{
    public double genericCalc() {
        return genericCalc(Constants.avogadrosNum);
    }
    public double genericCalc(double avogadrosNum) {
        // real code here
    }
}

(顺便说一句,常数的值可能是错误的,或者有一个非常容易引起误解的名称。它很可能是
6.022E+23

为什么不预先计算结果,而不是调用pow,然后使用const?这是浪费的微瓦。“想想未来吧!”丹尼尔斯说。如果您的意思是使用Math.Pow预先计算结果并将其存储到一个变量中,那么我尝试了这个方法,但它不起作用,因为Math.Pow直到运行时才计算出来。我的意思是执行计算并硬编码结果。本质上,其他人所建议的。
const
字段不能标记为静态。这将无法编译。很好的捕获,在“+23”上。我甚至没有意识到这个答案的好处在于,你不知道C#spec中告诉你有关
const
表达式的确切部分,并且在不需要编辑的情况下编写了一个可接受的答案,并在5分钟内完成了它。@dudeprgm:我怀疑我确实编辑了它,但公平地说,是在5分钟的宽限期内:)