为什么IsLiteral对于小数返回false? [英] Why does IsLiteral return false for decimal?
问题描述
以下程序将使用 IsLiteral
public static class Program
{
public static void Main(string[] args)
{
foreach (var field in typeof(Program).GetFields())
{
System.Console.WriteLine(field.Name + " IsLiteral: " + field.IsLiteral);
}
System.Console.ReadLine();
}
public const decimal DecimalConstant = 99M;
public const string StringConstant = "StringConstant";
public const int IntConstant = 1;
public const double DoubleConstant = 1D;
}
对于所有类型,除十进制之外,它均适用
将返回false。
It works correctly for all types, except for decimal
is will return false.
有人可以解释这种现象吗?还有更好的方法来查看字段是否恒定吗?
Can anyone explain this behavior? And is there a better way to see if a field is constant?
推荐答案
从运行时开始,它不是常量角度-因为CLR基本上不了解十进制
;它不是原始类型。这就是为什么您也不能在属性中使用小数。
It's not a constant from a runtime perspective - because the CLR basically doesn't know about decimal
; it's not a primitive type. That's why you can't use decimals in attributes, too.
如果查看字段的IL,您会发现它起作用:
If you look at the IL for the fields, you can see this in action:
.field public static initonly valuetype [mscorlib]System.Decimal DecimalConstant
.custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor
(uint8, uint8, uint32, uint32, uint32) =
(01 00 00 00 00 00 00 00 00 00 00 00 63 00 00 00 00 00)
.field public static literal string StringConstant = "StringConstant"
.field public static literal int32 IntConstant = int32(0x00000001)
.field public static literal float64 DoubleConstant = float64(1.)
注意其他常量 的IL如何具有字面意义
,但 DecimalConstant
没有。相反,它只是一个应用了属性的只读字段。该属性允许其他编译器将字段视为常量并知道其值-例如,它可以出现在其他const表达式中。
Notice how the IL for the other constants does have literal
in it, but DecimalConstant
doesn't. Instead, it's just a read-only field with an attribute applied. The attribute allows other compilers to treat the field as a constant and know the value - so it can appear in other const expressions, for example.
然后有一个类型初始值设定项设置执行时的字段值:
There's then a type initializer to set the field value at execution time:
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldc.i4.s 99
IL_0002: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0007: stsfld valuetype [mscorlib]System.Decimal Program::DecimalConstant
IL_000c: ret
} // end of method Program::.cctor
再次,仅在 DecimalConstant
中出现运行时直接处理其他字段。
Again, this is only present for DecimalConstant
because the runtime handles the other fields directly.
这篇关于为什么IsLiteral对于小数返回false?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!