C# .NET 6是否有类似C++ std::is_arithmetic_v<T>的算术类型泛型约束?
.NET 6 中约束泛型参数为算术类型的方案
.NET 6 里没有像 C++ std::is_arithmetic_v<T> 那样的原生编译时泛型约束来直接限制参数为算术类型,你尝试开启的<EnablePreviewFeatures>true</EnablePreviewFeatures>也不会生效——泛型数学是.NET 7才正式引入的特性,.NET 6的预览特性包并不包含这部分功能。
在.NET 6里,你可以通过以下两种方式实现类似效果:
1. 运行时类型检查
这是最直接可行的替代方案,在方法内部判断类型是否属于算术类型,不符合则抛出异常:
public void ProcessArithmeticValue<T>(T value) { var typeCode = Type.GetTypeCode(typeof(T)); if (!IsArithmeticType(typeCode)) { throw new ArgumentException("参数必须是算术类型", nameof(value)); } // 你的业务逻辑代码 } private bool IsArithmeticType(TypeCode typeCode) { return typeCode switch { TypeCode.Byte or TypeCode.SByte or TypeCode.Int16 or TypeCode.UInt16 or TypeCode.Int32 or TypeCode.UInt32 or TypeCode.Int64 or TypeCode.UInt64 or TypeCode.Single or TypeCode.Double or TypeCode.Decimal => true, _ => false }; }
这种方式的缺点是错误只能在运行时被发现,无法在编译阶段就阻止非法类型传入。
2. 自定义标记接口(局限性较大)
你可以定义一个空的标记接口,然后通过包装类或扩展逻辑为所有算术类型关联这个接口,但这种方式需要编写大量冗余代码,而且内置值类型无法直接实现接口,实用性不高,一般不推荐。
如果想要编译时的强约束,唯一的办法是升级到.NET 7及以上版本,利用泛型数学提供的INumber<T>、INumberBase<T>等接口作为泛型约束,示例:
public float Calculate<T>(T input) where T : INumber<T> { // 逻辑实现 }
内容的提问来源于stack exchange,提问作者神楽坂 綾乃
相关产品推荐
相关产品推荐

