为何C#中decimal转long的显式转换运算符会被隐式调用致精度丢失?
C#中显式转换被隐式调用导致精度丢失的问题
我遇到一个问题:以下C#程序会静默且隐式地调用decimal转long的显式转换运算符,进而导致精度丢失。按照我的认知,C#中的显式运算符不应被语言隐式调用,尤其是这种会丢失精度的转换(比如1.1M被转为1L),这种异常行为已经导致我的程序出现Bug。
简化代码示例
// 自定义数值类型 struct Num { long Raw; public static implicit operator Num(long v) => new Num { Raw = v }; } class Program { static void Main() { decimal d = 1.1m; // 下面这行代码会隐式将d转为long(静默丢失精度),然后调用Num.op_Implicit(long) Num num = (Num)d; // <=== 这不应该通过编译??? } }
生成的IL代码
从生成的IL代码可以看到,System.Decimal::op_Explicit被调用了,尽管我们从未主动请求这个操作:
IL_0000: ldc.i4.s 11 IL_0002: ldc.i4.0 IL_0003: ldc.i4.0 IL_0004: ldc.i4.0 IL_0005: ldc.i4.1 IL_0006: newobj instance void [mscorlib]System.Decimal::.ctor(int32, int32, int32, bool, uint8) IL_000b: stloc.0 IL_000c: ldloc.0 IL_000d: call int64 [mscorlib]System.Decimal::op_Explicit(valuetype [mscorlib]System.Decimal) // <=== ??? IL_0012: call valuetype Num Num::op_Implicit(int64) IL_0017: stloc.1 IL_0018: ret
内容的提问来源于stack exchange,提问作者kaalus
相关产品推荐
相关产品推荐

