How to make a run-time constant be a compile-time constant?

So, I am working on a chemistry-based project and ran into this difficult problem. I have a bunch of functions that do chemistry type calculations, and you want to pass the avogadros number as the default parameter for the function. Let me just talk to the code:

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

Edit: didn't know about exponential format, thanks guys

+7
c #
source share
4 answers

You cannot, in general. Everything related to the method call will not be a compile-time constant, as for the compiler.

What you can do is express a double literal using scientific notation:

 public const double AvogadrosNumber = 6.022e-22; 

So, in this particular case, you can write it without loss of readability.

In other settings, as long as the type is one of primitive types or decimal , you can simply write the constant as a literal and use a comment to explain how you got it. For example:

 // Math.Sqrt(Math.PI) public const double SquareRootOfPi = 1.7724538509055159; 

Note that even if method calls cannot be used in constant expressions, other operators may be used. For example:

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

For more information about what is allowed within a constant expression, see section 7.19 of the C # 5 specification.

+14
source share

Just specify the avgadros number as scientific notation:

 class Constants { public double const avogadrosNum = 6.022e-22; } 
+2
source share

For compile-time constant, you need to use the const keyword. But to use it, your expression must also be a compile-time constant, as you noticed: you cannot use functions like Math.Pow .

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

If you cannot or do not want to process the constant into a compile-time constant, you cannot use it in compile-time contexts, but you can work around this by overloading so that the run-time value can be used as a default argument sort:

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

(By the way, the value of the constant is either incorrect or has a very misleading name. Most likely, it will be 6.022E+23 )

+2
source share

You can do this in exponential format: 6.022E-22

+1
source share

All Articles