C#显式类型转换未触发自定义implicit转换运算符问题
问题原因
你遇到的问题和隐式转换能否用于显式场景无关,核心是C#的用户自定义转换运算符是编译期静态绑定的,不会在运行时对object类型的转换生效:
你实现的CompareTo方法入参是object类型,编译器编译(SqlBigInt)other这段代码时,只知道other是object类型,不知道它实际存储的是long值,因此不会匹配你写的long到SqlBigInt的转换逻辑,只会尝试运行时直接强制类型转换,而object和SqlBigInt没有继承关系,自然抛出InvalidCastException。
补充说明:隐式转换运算符是支持在显式转换场景调用的,只要编译期能明确原类型符合转换要求,比如下面的代码完全可以正常运行:
long val = 10; // 显式转换场景,会正常调用你写的隐式转换运算符 SqlBigInt bigInt = (SqlBigInt)val;
解决方案
修改CompareTo方法的逻辑,先判断入参的实际类型再处理:
public override int CompareTo(object other) { // 先判断实际类型是long的场景 if (other is long longVal) { // 此时明确类型是long,会触发自定义隐式转换 return CompareTo(longVal); } // 本身就是SqlBigInt类型的场景 if (other is SqlBigInt sqlVal) { return CompareTo(sqlVal); } // 可根据需求补充long?等其他兼容类型的判断 throw new ArgumentException("不支持与当前类型的对象比较"); }
此外建议你额外实现泛型版本的IComparable<SqlBigInt>、IComparable<long>接口,同时重载</>/<=/>=等比较运算符,这样NUnit执行断言时会优先走类型匹配的重载,不会触发object参数的比较逻辑,性能和稳定性都更高。
内容的提问来源于stack exchange,提问作者Helena
相关产品推荐
相关产品推荐

