evaluate expression at compile time
For numerical constants I see two options:
Option one: use static readonly (calculated once at startup):
class MyCalc
{
private static readonly double spi = Math.Sin(Math.PI);
private static readonly double pi = Math.PI;
public void Execute()
{
// .. whatever
}
}
Option two: perform calculations with your pocket calculator and hardcode those constants:
class MyCalc
{
// Math.Sin(Math.Pi)
private const double spi = 0;
// Math.Pi
private const double pi = 3.141592653589793;
public void Execute()
{
// .. whatever
}
}
I'm not sure, if the compiler can completely optimize away option one in a calculation but it should be the most readable and maintainable way.
If you are looking for doing as much at compile-time as possible, things get harder. Under C++ you have templates. I find them cumbersome to write but people get amazing things done with it. It seems it got easier with compile time functions but I haven't tried them yet. D have CTFE which is really powerful. But D is a niche and I would avoid to write any serious code in it. I am not aware of other languages with a considerable explicit precompilation evaluation but I'm sure there are some.
Compilers are quite smart these days. Chances are good that a compiler might see an opportunity to inline an optimize a function call without an hint. With DotNet 4.5, we've got the AggressiveInlining-attribute so we might to be able to force the compiler into the right direction. C/C++ have something similar and there had been problems. General advice from my side would be to avoid inline
until you exactly know what you are doing.
If you really wan't to go this way from C#, the best option in my eyes would be to write your functionality in C++ using the mentioned features, write an easy to use C-interface and call it by PInvoke. But do yourself a favor and measure before if it is really worth it. Never forget the two rules of optimization:
- Don't
- Don't yet (experts only)
There is the [Pure] attribute for methods which have no side effects. However, this is only used for code analysis and not by the compiler (at the moment). However, this might change in the future.
JetBrains ReSharper provides a similar [Pure] attribute for the same purpose (code analysis).
So, for the moment, you need a workaround like a value pre-calculated by you, best with a comment for someone else to know the source of the value:
const double spi = 0.0; // Math.Sin(Math.PI)
or
static readonly double spi = Math.Sin(Math.PI);
which of course calculates the value to runtime, which you don't want.