为何在转换运算符中double会被隐式转换为int?
如何仅允许int到自定义结构体的显式转换,禁止double/decimal的转换
问题原因
你遇到的情况是C#类型转换规则导致的:编译器会自动组合多步转换来完成显式转换操作:
- 执行
(TestDecimal)12.34时,编译器先把double显式转成int(直接截断小数部分),再调用你定义的int → TestDecimal显式转换,最终得到丢失小数的结果。 - 执行
(TestDecimal)12.34m时,同理,编译器先将decimal显式转成int,再转换为TestDecimal,同样丢失小数部分。
解决方案
要在编译阶段就彻底禁止这类转换,你可以声明从double和decimal到TestDecimal的显式转换运算符,并标记为过时且触发编译错误,这样编译器会直接报错,而非允许转换执行。
修改后的完整代码:
using System; readonly struct TestDecimal { public decimal Value { get; } TestDecimal(decimal value) => Value = value; // 仅保留允许的int到TestDecimal显式转换 public static explicit operator TestDecimal(int x) => new(x); // 禁止double转换,编译时直接报错 [Obsolete("不允许从double转换为TestDecimal", error: true)] public static explicit operator TestDecimal(double x) => throw new NotSupportedException(); // 禁止decimal转换,编译时直接报错 [Obsolete("不允许从decimal转换为TestDecimal", error: true)] public static explicit operator TestDecimal(decimal x) => throw new NotSupportedException(); }
效果验证
现在再尝试写(TestDecimal)12.34或(TestDecimal)12.34m时,编译器会直接抛出错误,彻底阻止这类不符合预期的转换,完全满足你“仅支持int类型转换”的需求。
内容的提问来源于stack exchange,提问作者Dave Cousineau
相关产品推荐
相关产品推荐

