【发布时间】:2012-05-04 19:01:46
【问题描述】:
我已经构建了一个抽象类,用于处理我们产品的命令行选项。
只需要创建一个从 AbstractOptions 继承的类,用修饰字段填充它,然后调用继承的 Parse(args) 方法,通过反射自动填充来自命令行的值。在命令行中找不到的值保留其当前(默认)值。
然后,应用程序只需要检查选项字段来获取它们的值。 AbstractOptions 类提供了更多功能,如帮助输出等,但它不是重点。
简短示例:
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");
}
现在,我遇到的问题是,由于编译器没有找到任何实际更改 SignalOptions 类的值的代码,它只是内联了在代码中使用它们的值。我通过要求类中的所有 'option' 字段都是 volatile 来规避这个问题,因此没有应用优化,并且工作正常,但不幸的是 volatile 关键字在 double 上无效。
我在网上花了很多时间试图找到解决方法,但没有成功。有没有办法阻止对字段的优化或以其他方式欺骗编译器/抖动以为它们是在运行时使用的?
我还希望尽可能减少调用应用程序的责任。
谢谢
【问题讨论】:
-
我强烈怀疑您误诊了这个问题。请展示一个简短但完整的程序来说明问题。
-
编译器如何知道是否使用了公共类的公共字段?它可以在不属于当前构建的程序集中使用
-
另外:
[MethodImpl(MethodImplOptions.NoInlining)]在字段上无效,所以我怀疑这是您的真实代码 -
我很确定
volatile没有解决您的问题,只是掩盖了它。你显然在opts.Parse中做错了什么,但没有相关代码,我们无法告诉你是什么。 -
您的代码(您尚未发布的代码!)几乎是可笑的错误。这就是为什么发布所有相关代码很重要的原因。这样的问题只会浪费大家的时间。
标签: c# optimization