我工作在一个数学库,并且由于与工作的内在困境double我编码人人平等的比较型a == b的Math.Abs(a - b) <= epsilon.
此外,默认情况下,我希望以最大考虑精度生成格式化的字符串.也就是说,如果epsilon是0.001我想要的默认格式N3.
我很高兴我做了以下事情:
public static class Math3D
{
internal const int ROUND = 3;
public const double Epsilon = 1e-ROUND;
}
Run Code Online (Sandbox Code Playgroud)
......我收到了编译错误.显然这是不允许的.
有了这个限制,我认为我无法将两个相互依赖的常量定义为consts.显然我可以定义Epsilon为只读字段,但我觉得这样做在概念上是错误的.我错过了一个如何做到这一点的明显方法吗?
jas*_*son 10
如果你可能要改变它,你应该readonly在这里使用.const应该真的用于永远不会改变的事情,比如π.这样做的原因是因为之间的细微差别的const和readonly.
主要问题是,如果你改变了它的值const,你必须重新编译所有使用它的依赖客户端const,否则你可以用脚射击自己,非常糟糕.因此,对于可能发生变化的值,请勿使用const,使用readonly.
因此,如果该值永远不会改变,只是使用const再不用担心定义Epsilon来讲ROUND,只是说:
internal const int ROUND = 3;
public const double Epsilon = 1e-3;
Run Code Online (Sandbox Code Playgroud)
如果你真的想确保在不改变另一个的情况下不小心改变一个,你可以在构造函数中添加一个小的检查:
if (Epsilon != Math.Pow(10, -ROUND)) {
throw new YouForgotToChangeBothConstVariablesException();
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以添加条件编译,以便只在调试版本中编译.
如果是打算改变,使用static readonly:
internal readonly int ROUND = 3;
public static readonly double Epsilon = Math.Pow(10, -ROUND);
Run Code Online (Sandbox Code Playgroud)
有了这个限制,我认为我无法将两个相互依赖的常量定义为consts.[...]我错过了一个明显的方法来做到这一点吗?
不,你需要使用Math.Pow或Math.Log在两者之间进行某种数学运算ROUND,Epsilon而这些数学运算时使用它们是不可接受的const.您可以编写一个微型代码生成器,根据单个输入值吐出这两行代码,但我真的质疑投入时间的价值.