如何将整数转换为INumber<T>泛型数字类型?
C#泛型数字类型中整数转泛型T的优雅实现
在基于INumber<T>约束的泛型类中,直接对泛型T和整数进行运算会触发CS0019错误(运算符/无法应用于T和int类型)。你之前的临时方案需要逐个判断数字类型,代码冗余且扩展性不足,其实利用.NET内置的数字接口方法就能完美解决。
最优解决方案
利用INumber<T>继承的INumberBase<T>接口提供的静态转换方法,无需手动枚举类型,自动支持所有符合约束的数字类型(包括内置类型和自定义数字类型):
public static class ClassA<T> where T : struct, INumber<T> { public static T MethodA(T[][] matrix, T[] vector) { T result = T.Zero; int m = matrix.Length; for (int i = 0; i < m; i++) { result += MethodB(matrix[i], vector); } // 使用CreateChecked将整数转换为泛型T(溢出时抛出异常) T divisor = T.CreateChecked(m * 2 + 1); return result / divisor; } public static T MethodB(T[] vector1, T[] vector2) { T result = T.One; return result; } }
方法说明
INumberBase<T>提供了三种核心转换方法,可根据需求选择:
T.CreateChecked<TOther>(TOther value):转换时若发生溢出,直接抛出OverflowException,适合需要严格校验的场景T.CreateTruncating<TOther>(TOther value):溢出时直接截断超出范围的部分(例如int转byte时,超出255的数值会被截断)T.CreateSaturating<TOther>(TOther value):溢出时自动取当前类型的最大值或最小值,避免异常
这些方法的优势:
- 自动适配所有
INumber<T>实现类型,包括int、double、float、decimal等内置类型 - 无需装箱拆箱,性能更优
- 支持自定义数字类型,只要正确实现
INumber<T>接口即可直接使用
临时方案的不足
你之前的CreateT方法存在以下问题:
- 需要手动枚举所有可能的数字类型,代码冗余且容易遗漏(比如long、ushort、decimal等)
- 装箱拆箱操作会带来不必要的性能开销
- 无法自动支持自定义数字类型,扩展性差
内容的提问来源于stack exchange,提问作者Fixolito
相关产品推荐
相关产品推荐

