如何在C#中汇总通用数字?

asm*_*smo 5 c# generics

可能重复:
仅对整数的C#泛型约束

正如您在下面的代码中看到的,我需要计算两个通用数字的总和.

public class NumberContainer<T>
{
    public T ValueA { get; private set; }
    public T ValueB { get; private set; }
    public T Total { get { return ValueA + ValueB; } }
}
Run Code Online (Sandbox Code Playgroud)

但是,不可能直接添加两个T值,这会导致编译器错误如下:

运算符'+'不能应用于'T'和'T'类型的操作数

鉴于我不打算将T用于表示数字的值类型(short,ushort,int,uint等)以外的其他任何东西,我怎么能执行总和呢?(效率是一个需要考虑的因素)

das*_*ght 12

你可以用LINQ的"小魔法"来做到这一点:

private static readonly Func<T, T, T> adder;
static NumberContainer() {
    var p1 = Expression.Parameter(typeof (T));
    var p2 = Expression.Parameter(typeof (T));
    adder = (Func<T, T, T>)Expression
        .Lambda(Expression.Add(p1, p2), p1, p2)
        .Compile();
} 
public T Total { get { return adder(ValueA, ValueB); } }
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是,即使使用不支持添加的类型实例化,此代码也会编译; 当然它会在运行时抛出异常.另一个好处是,它应该与用户定义的运算符一起使用.NumberContainerT+


M.B*_*ock 6

除了使用LINQ之外,如果您使用的是.NET 4,则可以使用dynamic:

static T Add<T>(T x, T y) 
{
    dynamic dx = x, dy = y;
    return dx + dy;
}
Run Code Online (Sandbox Code Playgroud)

在您的代码示例中,这变为:

public class NumberContainer<T> where T: struct
{
    public T ValueA { get; private set; }
    public T ValueB { get; private set; }
    public T Total { get { return ((dynamic)ValueA) + ((dynamic)ValueB); } }
}
Run Code Online (Sandbox Code Playgroud)

但这种方法并不能确保安全.如果T是一些不支持+你的随机结构,你最终会得到一个异常(我认为).