You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET 7.0中编写兼容INumber与double的通用随机选择函数

解决.NET 7泛型数学中INumber与double的乘法兼容问题

针对泛型类型T(约束为INumber<T>)无法和double直接相乘,且整数类型转换会出现bug的问题,核心解决思路是先将泛型数值转换为浮点类型完成计算,再通过INumber<T>提供的类型安全转换方法转回泛型类型,同时针对整数类型处理舍入逻辑。

修改后的完整代码

public static T RollWithVariance<T>(T lower, T middle, T higher, double percentageRoll, bool useVariance) where T : INumber<T>
{
    if (lower > higher)
        throw new ArgumentException($"The parameter for lower: {lower} must be lower than higher: {higher}", nameof(lower));
    if (lower > middle)
        throw new ArgumentException($"The parameter for lower: {lower} must be lower than middle: {middle}", nameof(lower));
    if (middle > higher)
        throw new ArgumentException($"The parameter for middle: {middle} must be lower than higher: {higher}", nameof(middle));

    if (lower == higher && lower != middle)
        throw new ArgumentException("The parameters for the lower and upper bound are the same, but the middle is another value. Please make sure either all three are the same, or none are the same. (Alternatively, consider not using this function for this invoke.)", nameof(lower));

    if (lower == middle && middle == higher)
        return middle;

    if (useVariance)
    {
        // 先将泛型差值转换为double计算,再通过截断转换回T(适合整数类型)
        var range = (double)(higher - lower);
        var offset = range * percentageRoll;
        return lower + T.CreateTruncating(offset);
        
        // 如果需要四舍五入而非截断,替换为:
        // return lower + T.CreateRounding(offset, MidpointRounding.AwayFromZero);
    }
    else
    {
        return middle;
    }
}

关键说明

  1. 类型转换逻辑:

    • 先将higher - lower的泛型结果转换为double,和percentageRoll完成乘法计算,规避泛型与double直接运算的编译错误。
    • 使用INumber<T>的静态转换方法处理类型回转:
      • CreateTruncating直接截断小数部分,适合向下取整的整数场景;
      • CreateRounding支持指定舍入规则(如MidpointRounding.AwayFromZero),适合需要四舍五入的场景;
      • CreateChecked会在转换结果超出T范围时抛出异常,适合需要溢出检查的场景。
  2. 整数类型bug规避:
    直接将[0,1]范围的percentageRoll转换为整数类型会得到0,而先计算浮点偏移量再转换,能得到符合预期的整数结果(比如int类型下,(5-1)*0.75=3,转换后就是3)。

内容的提问来源于stack exchange,提问作者Sakorona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 10:50:24