为什么我的常量或静态成员没有初始化?
Why is my const or static member not initialized?
我一直在为这个问题摸不着头脑。我怀疑我在这里只是愚蠢,但我似乎无法获得要初始化的 const 或静态成员,因此我可以在整个 class.
中使用它
这是一个说明我的问题(或者更确切地说是我的误解)的例子:
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 而不是初始化值。
我错过了什么?
原因是有Integer division
。
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded.88) If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.
尝试关注 .
private const double fSectionLengthTolerancePerInch = 1.0 / (20 * 12);
您需要至少转换一个整数,因为您要除以两个整数,这也会产生一个整数(在您的情况下四舍五入为 0):
private const double fSectionLengthTolerancePerInch = (double)1 / (20 * 12);
然后你可以使用:
Console.WriteLine("instance c'tor: " + fSectionLengthTolerancePerInch);
>>> 0.00416666666666667
这是一个典型的 "conversion too late" 缺陷,我希望 C# 编译器对此发出警告。您正在对整数进行所有算术运算,然后将结果分配给双精度数。结果是一个整数,整数中的 1 / 240
为零。在双打中做算术:1.0 / 240.0
.
我们还看到这个缺陷涉及 non-constants,例如
percentDone = doneSoFar / totalWork;
如果被除数是整数并且结果是双精度数,那么结果很可能是零。
还要注意涉及乘法的相同 "conversion too late" 缺陷:
double microseconds = seconds * 1000000;
如果 seconds
是 int 并且超过几千那么这将溢出整数 before 它分配给 double,而不是你想要的,这是首先转换为 double 并在 double 中进行乘法。同样,应该 1000000.0
向编译器提示您希望以更高的精度完成操作。
您对整数进行运算 1 / (20 * 12)
。结果居然是0
。您必须至少有一个数字要加倍才能得到加倍的结果:1.0 / (20 * 12)
.
改变
private const double fSectionLengthTolerancePerInch = 1 / (20 * 12);
至
private const double fSectionLengthTolerancePerInch = 11.0
我一直在为这个问题摸不着头脑。我怀疑我在这里只是愚蠢,但我似乎无法获得要初始化的 const 或静态成员,因此我可以在整个 class.
中使用它这是一个说明我的问题(或者更确切地说是我的误解)的例子:
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 而不是初始化值。
我错过了什么?
原因是有Integer division
。
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded.88) If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.
尝试关注 .
private const double fSectionLengthTolerancePerInch = 1.0 / (20 * 12);
您需要至少转换一个整数,因为您要除以两个整数,这也会产生一个整数(在您的情况下四舍五入为 0):
private const double fSectionLengthTolerancePerInch = (double)1 / (20 * 12);
然后你可以使用:
Console.WriteLine("instance c'tor: " + fSectionLengthTolerancePerInch);
>>> 0.00416666666666667
这是一个典型的 "conversion too late" 缺陷,我希望 C# 编译器对此发出警告。您正在对整数进行所有算术运算,然后将结果分配给双精度数。结果是一个整数,整数中的 1 / 240
为零。在双打中做算术:1.0 / 240.0
.
我们还看到这个缺陷涉及 non-constants,例如
percentDone = doneSoFar / totalWork;
如果被除数是整数并且结果是双精度数,那么结果很可能是零。
还要注意涉及乘法的相同 "conversion too late" 缺陷:
double microseconds = seconds * 1000000;
如果 seconds
是 int 并且超过几千那么这将溢出整数 before 它分配给 double,而不是你想要的,这是首先转换为 double 并在 double 中进行乘法。同样,应该 1000000.0
向编译器提示您希望以更高的精度完成操作。
您对整数进行运算 1 / (20 * 12)
。结果居然是0
。您必须至少有一个数字要加倍才能得到加倍的结果:1.0 / (20 * 12)
.
改变
private const double fSectionLengthTolerancePerInch = 1 / (20 * 12);
至
private const double fSectionLengthTolerancePerInch = 11.0