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

求助:如何实现支持数值类型的泛型Average<T>类

解决泛型Average数值类型约束的问题

我明白你卡在这里一整天有多头疼——你之前的思路问题出在:int并没有继承你定义的NumericBase<int>,所以Average<int>根本满足不了where T:NumericBase<T>的约束,自然没法按预期使用。下面给你两种可行的解决方案,分别适配不同的.NET版本:

方案1:.NET 7及以上(推荐,最简洁)

.NET 7引入了System.Numerics.INumber<T>接口,它为所有数值类型(int、float、double等)提供了统一的数值运算能力,完美解决你的需求:

using System.Numerics;

public class Average<T> where T : INumber<T>
{
    private T _sum = T.Zero;
    private int _count = 0;

    // 向实例添加元素
    public void Add(T item)
    {
        _sum += item;
        _count++;
    }

    // 计算平均值
    public T Average()
    {
        if (_count == 0)
            throw new InvalidOperationException("无法计算空集合的平均值,请先添加元素。");
        
        // 将计数转换为T类型,确保除法运算类型匹配
        return _sum / T.CreateChecked(_count);
    }

    // 重置实例状态
    public void Reset()
    {
        _sum = T.Zero;
        _count = 0;
    }
}

使用方式完全符合你的预期:

Average<int> av = new Average<int>();
av.Add(3);
av.Add(4);
int averageValue = av.Average(); // 结果为3(int整数除法特性)
av.Reset();

// 也支持float等其他数值类型
Average<float> floatAv = new Average<float>();
floatAv.Add(3.5f);
floatAv.Add(4.5f);
float floatAvg = floatAv.Average(); // 结果为4.0f

方案2:兼容.NET Framework/.NET 6及以下

如果你的项目无法升级到.NET 7,可以自定义一个数值运算接口,为每个需要支持的数值类型实现该接口,再通过隐式转换让使用更顺畅:

第一步:定义数值运算接口

public interface INumeric<T>
{
    // 加法运算
    T Add(T other);
    // 除以整数的运算
    T Divide(int divisor);
    // 获取该类型的零值
    static abstract T Zero { get; }
}

第二步:为int实现接口(以int为例,其他类型类似)

public struct NumericInt : INumeric<int>
{
    private readonly int _value;

    public NumericInt(int value) => _value = value;

    public int Add(int other) => _value + other;

    public int Divide(int divisor) => _value / divisor;

    public static int Zero => 0;

    // 隐式转换,允许直接传入int类型值
    public static implicit operator NumericInt(int value) => new NumericInt(value);
    // 隐式转换,允许直接将结果转为int
    public static implicit operator int(NumericInt numeric) => numeric._value;
}

第三步:实现泛型Average类

public class Average<T> where T : INumeric<T>
{
    private T _sum = INumeric<T>.Zero;
    private int _count = 0;

    public void Add(T item)
    {
        _sum = _sum.Add(item);
        _count++;
    }

    public T Average()
    {
        if (_count == 0)
            throw new InvalidOperationException("无法计算空集合的平均值,请先添加元素。");
        
        return _sum.Divide(_count);
    }

    public void Reset()
    {
        _sum = INumeric<T>.Zero;
        _count = 0;
    }
}

使用示例:

Average<NumericInt> av = new Average<NumericInt>();
av.Add(3); // 隐式转换为NumericInt
av.Add(4);
int averageValue = av.Average(); // 隐式转换回int
av.Reset();

你只需要为需要支持的数值类型(比如float、double、byte)都实现INumeric<T>接口,就能复用这个Average类了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 11:32:45