I have built an abstract class that is used to handle command line options for our products.
One need only to create a class inheriting from AbstractOptions, fill it with decorated fields and call the inherited Parse(args) method to have it automatically filled through reflection with values from the command line. Values that were not found on the command line retain their current (default) values.
Then, the application needs only to check the option fields to get their value. The AbstractOptions class provides more features, like help output, etc, but it is beside the point.
Short example:
public class SignalOptions: AbstractOptions
{
[Option("-i, --iterations", "Number of iterations (0 = infinite).")]
volatile public int NumberOfIterations;
[Option("-s, --silent", "Silent mode, only display final results.")]
volatile public bool Silent;
[Option("-w, --zwindow", "Window size for z-score analysis.")]
volatile public int ZWindow = 7;
[Option("-a, --zalert", "z-score value to consider as peak.")]
public double ZAlert = 2.1;
}
static void Main(string[] args)
{
var opts = new SignalOptions();
opts.Parse(args)
// If optimizations are turned off, SILENT will be written or not
// followind presence or absence of the --silent switch on the command line.
// If optimizations are turned on, SILENT will never be written.
// The reflection part is working fine. I suspect the problem is that
// the compiler of the jitter having never found this set anywhere simply inlines
// the value 'false' inthe if, because when I step on it, it shows me the value as
// true or false, but has the same behavior no matter what value opts.Silence has.
if( opts.Silent )
Console.Writeline("SILENT");
}
Now, the problem I have is that since the compiler does not find any code actually changing the values of the SignalOptions class, it simply inlines the values where they are used in the code. I have circumvent the issue by requiring that all ‘option’ fields in the class be volatile, so no optimization is applied, and it works fine, but unfortunately the volatile keyword is not valid on a double.
I have spent much time on the net trying to find a workaround, without success. Is there anyway to either prevent optimizations on the fields or otherwise fool the compiler/jitter into thinking they are used at runtime?
I also would like to put as less as possible the onus on the calling application.
Thanks
I have a local copy here with
Parsewritten as the rather opaque:It works fine. I do not believe the problem is what you think it is.