为什么我的const或静态成员没有初始化?

时间:2016-01-10 17:19:47

标签: c# static initialization const static-initialization

我一直在抓挠这个问题。我怀疑我;我只是在这里愚蠢,但我似乎无法获得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而不是初始值。

我错过了什么?

5 个答案:

答案 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