为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 IsLiteral 为十进制返回 false?

为什么 IsLiteral 为十进制返回 false?

C#
慕丝7291255 2021-11-07 19:51:03
以下程序将打印字段以及是否使用常量 IsLiteralpublic 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;}它适用于所有类型,除了decimalis 将返回 false。谁能解释这种行为?有没有更好的方法来查看字段是否恒定?
查看完整描述

1 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

从运行时的角度来看,它不是一个常量- 因为 CLR 基本上不知道decimal; 它不是原始类型。这就是你不能在属性中使用小数的原因。


如果您查看这些字段的 IL,您可以看到以下内容:


.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确实有literal它,但DecimalConstant没有。相反,它只是一个应用了属性的只读字段。该属性允许其他编译器将该字段视为常量并知道其值 - 例如,它可以出现在其他 const 表达式中。


然后有一个类型初始化器来在执行时设置字段值:


.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因为运行时直接处理其他字段而存在。


查看完整回答
反对 回复 2021-11-07
  • 1 回答
  • 0 关注
  • 162 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信