C#中能否将可为空数值类型的重载方法改写为泛型数学方法?
问题描述
想要将以下针对可为空数值类型的重载方法:
bool Foo(byte? value) { return value is null || value > 0; } bool Foo(short? value) { return value is null || value > 0; }
改写为使用泛型数学的泛型方法:
bool Foo<TNumber>(TNumber? value) where TNumber : INumber<TNumber> { return value is null || TNumber.IsPositive(value); }
但尝试时出现编译器错误CS0313,想问当前C#是否支持这种实现方式?
解答
截至C# 12,不支持直接将INumber<TNumber>约束的泛型类型与TNumber?结合使用,这正是CS0313错误的根源——编译器无法解析TNumber?的合法类型,因为INumber<TNumber>约束不限制TNumber必须是值类型(尽管实际数值类型都是值类型,但约束本身允许引用类型实现该接口)。
要实现符合需求的泛型版本,需要调整约束条件,明确限定TNumber为非nullable值类型:
- 添加
struct约束,配合INumber<TNumber>,让编译器确定TNumber是值类型,此时TNumber?会被正确识别为可为空值类型 - 由于
value是可为空值类型,需要先取出其有效值再调用IsPositive方法
调整后的代码示例:
bool Foo<TNumber>(TNumber? value) where TNumber : struct, INumber<TNumber> { return value is null || TNumber.IsPositive(value.Value); }
也可以通过模式匹配简化取值逻辑,让代码更简洁:
bool Foo<TNumber>(TNumber? value) where TNumber : struct, INumber<TNumber> { return value is not { } num || TNumber.IsPositive(num); }
内容的提问来源于stack exchange,提问作者Michu01
相关产品推荐
相关产品推荐

