How to sum total numbers in C #?

Possible duplicate:
General C # restriction for integers

As you can see in the following code, I need to calculate the sum of two common numbers.

public class NumberContainer<T>
{
    public T ValueA { get; private set; }
    public T ValueB { get; private set; }
    public T Total { get { return ValueA + ValueB; } }
}

However, it is not possible to directly add two T values, which leads to a compiler error:

The '+' operator cannot be applied to operands of type 'T' and 'T'

Given that I do not intend to use T for anything other than value types that represent numbers (short, ushort, int, uint, etc.), how could I execute the sum? (effectiveness is a factor to consider)

+5
source share
4 answers

You can do this with LINQ's “little magic”:

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); } }

, , NumberContainer T, ; , . , +.

+12

LINQ, .NET 4, dynamic:

static T Add<T>(T x, T y) 
{
    dynamic dx = x, dy = y;
    return dx + dy;
}

:

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); } }
}

. T - , +, ( ).

+5

You can specify a constraint for Tthat it should be a structure, and perhaps it implements IConvertable, and then use Convert.

public class NumberContainer<T>
        where T : struct, IConvertible
    {
        public T ValueA { get; private set; }
        public T ValueB { get; private set; }
        public T Total {
            get
            {
                // do type checking here, then:

                return (T)Convert.ChangeType(
                    Convert.ToDouble((object)ValueA) +
                    Convert.ToDouble((object)ValueB), typeof(T));
            } 
        }
    }

However, there is no way with generics to guarantee that T is an integer or floating-point type at compile time. However, you can check it at runtime and throw an exception.

+1
source

You can see this as an abstract base class and output certain classes that set the value of T and provided an implementation for Total

public abstract class NumberContainer<T>
    where T: struct
{
    public T ValueA { get; private set; }
    public T ValueB { get; private set; }
    public abstract T Total();
}

public class IntContainer : NumberContainer<int>
{
    public override int Total()
    {
        return ValueA + ValueB;
    }
}
+1
source

All Articles