我一直在抓挠这个问题。我怀疑我;我只是在这里愚蠢,但我似乎无法获得const或静态成员进行初始化,所以我可以在整个课程中使用它。
这是一个展示我的问题(或者更确切地说是我的误解)的例子:
using System;
namespace ConstExample
{
public class HasImmutableMember
{
// static private double fSectionLengthTolerancePerInch = 1 / (20 * 12); // tolerance is 1" per every 20'
private const double fSectionLengthTolerancePerInch = 1 / (20 * 12); // tolerance is 1" per every 20'
static HasImmutableMember()
{
Console.WriteLine("static c'tor: " + fSectionLengthTolerancePerInch);
}
public HasImmutableMember()
{
Console.WriteLine("instance c'tor: " + fSectionLengthTolerancePerInch);
}
}
public class Program
{
public void Main(string[] args)
{
HasImmutableMember instance = new HasImmutableMember();
}
}
}
控制台输出为:
static c'tor: 0
instance c'tor: 0
无法在const成员声明中设置断点,但如果我使用静态版本,我可以。两者都没能给我我想要的东西。静态成员声明确实在静态c'tor或实例c'tor之前被命中。正如预期的那样,静态c'tor在实例c'tor之前被击中。但是在静态和实例c'tor中,我的成员的值是0而不是初始值。
我错过了什么?
答案 0 :(得分:5)
这是一个经典的#34;转换太晚了#34;我希望C#编译器警告的缺陷。您正在以整数执行所有算术运算,然后将结果分配给double。结果是整数,整数中的1 / 240
为零。算术是双倍的:1.0 / 240.0
。
我们也看到这个涉及非常数的缺陷,例如,
percentDone = doneSoFar / totalWork;
如果红利是整数而结果是双,则结果可能为零。
同时注意同样的转换太迟"涉及乘法的缺陷:
double microseconds = seconds * 1000000;
如果seconds
是int并且超过几千,那么这将在整数溢出之前它指定为double,而不是你想要的,这将转换为double first和在双打中进行乘法运算。同样,应该1000000.0
向编译器提示您希望以更高的精度完成操作。
答案 1 :(得分:1)
原因是Integer division
。
当整数被划分时,/运算符的结果是代数商,其中任何小数部分都被丢弃.88)如果商a / b是可表示的,则表达式(a / b)* b + a%b应该相等一个。
尝试以下操作。
private const double fSectionLengthTolerancePerInch = 1.0 / (20 * 12);
答案 2 :(得分:0)
你需要至少转换一个整数,因为你要分割两个整数,这也会得到一个整数(在你的情况下会四舍五入为0):
private const double fSectionLengthTolerancePerInch = (double)1 / (20 * 12);
然后你可以使用:
Console.WriteLine("instance c'tor: " + fSectionLengthTolerancePerInch);
>>> 0.00416666666666667
答案 3 :(得分:0)
您对整数1 / (20 * 12)
进行操作。结果实际上是0
。您必须至少有一个数字才能使结果变为双倍:1.0 / (20 * 12)
。
答案 4 :(得分:-2)
变化
private const double fSectionLengthTolerancePerInch = 1 / (20 * 12);
到
private const double fSectionLengthTolerancePerInch = 11.0