【问题标题】:Why is my const or static member not initialized?为什么我的 const 或 static 成员没有初始化?
【发布时间】:2016-01-10 17:19:47
【问题描述】:

我一直在抓挠和敲打这个。我怀疑我在这里只是愚蠢,但我似乎无法初始化一个 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 而不是初始化值。

我错过了什么?

【问题讨论】:

  • 好的,这是我的问题。典型的。我应该知道得更多。

标签: c# static initialization constants static-initialization


【解决方案1】:

这是一个经典的“转换太迟”缺陷,我希望 C# 编译器警告它。您正在以整数进行所有算术运算,然后将结果分配给双精度数。结果是一个整数,整数中的1 / 240 为零。用双打进行算术:1.0 / 240.0

我们也看到了这个涉及非常数的缺陷,例如,

percentDone = doneSoFar / totalWork;

如果被除数是整数并且结果是双精度数,那么结果很可能为零。

还要注意同样的涉及乘法的“转换太迟”缺陷:

double microseconds = seconds * 1000000;

如果seconds 是 int 并且超过几千,那么这将在整数中溢出 before 它分配给 double,而不是你想要的,即先转换为 double 并执行双倍乘法。同样,它应该是 1000000.0 向编译器提示您希望以更高的精度完成操作。

【讨论】:

    【解决方案2】:

    原因是有Integer division

    当整数相除时,/操作符的结果是去掉任何小数部分的代数商。88) 如果商 a/b 是可表示的,则表达式 (a/b)*b + a%b 应等于一个。

    尝试关注。

    private const double fSectionLengthTolerancePerInch = 1.0 / (20 * 12); 
    

    【讨论】:

      【解决方案3】:

      您对整数 1 / (20 * 12) 进行操作。结果实际上是0。你必须至少有一个数字是双倍的,才能得到双倍的结果:1.0 / (20 * 12)

      【讨论】:

        【解决方案4】:

        您需要转换至少一个整数,因为您将两个整数相除,这也会产生一个整数(在您的情况下会四舍五入为 0):

        private const double fSectionLengthTolerancePerInch = (double)1 / (20 * 12); 
        

        然后你可以使用:

        Console.WriteLine("instance c'tor: " + fSectionLengthTolerancePerInch);
        >>> 0.00416666666666667
        

        【讨论】:

          【解决方案5】:

          改变

          private const double fSectionLengthTolerancePerInch = 1 / (20 * 12);
          

          private const double fSectionLengthTolerancePerInch = 11.0
          

          【讨论】:

            猜你喜欢
            • 2014-09-08
            • 1970-01-01
            • 2018-10-13
            • 2011-05-18
            • 2021-06-13
            • 2020-09-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多