如何将可能为int或long的object类型值安全转换为long?
嘿,这个装箱值类型转换的坑我在遗留代码里踩过好多次了!直接强制转long之所以报错,是因为当object里装的是int时,CLR不允许直接把装箱的int强转成long——得先拆箱成int再转。结合你说的暂不重构的情况,给你几个安全又省心的方案:
方案1:类型匹配判断后拆箱转换
最直观的方式,先判断属性值的实际类型,再拆箱后转成long:
long id; var idValue = dBLockTabellenOptionen.Id; if (idValue is int intId) { id = intId; // int可以隐式转换为long,不会有问题 } else if (idValue is long longId) { id = longId; } else { // 兜底逻辑,根据你的业务需求调整:比如设默认值或抛自定义异常 throw new InvalidOperationException("Id属性的类型不符合预期"); }
这个方法是编译时安全的,完全不会触发拆箱异常,而且逻辑清晰,后续维护也容易看懂。
方案2:用Convert.ToInt64()一键处理
Convert类的方法已经帮你封装了装箱值类型的转换逻辑,内部会自动正确拆箱再转换,代码超级简洁:
// 直接转换,注意如果属性值是null会抛ArgumentNullException long id = Convert.ToInt64(dBLockTabellenOptionen.Id);
如果担心属性可能为null,可以加个null判断兜底:
// 给null值设默认0,或者根据业务改其他默认值 long id = dBLockTabellenOptionen.Id == null ? 0 : Convert.ToInt64(dBLockTabellenOptionen.Id);
这个方案最适合追求代码简洁的场景,甚至还能兼容其他可转换的数值类型(比如short)。
方案3:结合as运算符与可空值类型(C# 7+)
因为值类型不能直接用as转换,但可空值类型可以,这样能避免额外的强制转换操作:
long id; var intId = dBLockTabellenOptionen.Id as int?; if (intId.HasValue) { id = intId.Value; } else { var longId = dBLockTabellenOptionen.Id as long?; // 这里可以改成你需要的默认值,比如0 id = longId ?? throw new InvalidOperationException("Id属性类型无效"); }
这个方案和方案1逻辑类似,但用as的方式更符合C#的现代写法,代码更流畅。
补充:为什么直接强转会失败?
当
object类型的属性存储的是装箱的int时,它本质上是一个int的装箱实例。CLR不允许直接将装箱的int强制转换为long——必须先拆箱为int,再通过隐式或显式转换变成long。直接跨类型强制转换装箱值类型,就会触发System.InvalidCastException。
内容的提问来源于stack exchange,提问作者xeraphim
相关产品推荐
相关产品推荐

