C# Adding two Generic Values
There is no generic constraint that allows you to enforce operator overload. You may take a look at the following library. Alternatively if you are using .NET 4.0 you could use the dynamic
keyword:
public static T Add<T>(T number1, T number2)
{
dynamic a = number1;
dynamic b = number2;
return a + b;
}
Obviously this doesn't apply any compile time safety which is what generics are meant for. The only way to apply compile time safety is to enforce generic constraints. And for your scenario there is no constraint available. It's only a trick to cheat the compiler. If the caller of the Add method doesn't pass types that work with the + operator the code will throw an exception at runtime.
The solutions given here work well, but I thought I'd add another one which uses expressions
public static T Add<T>(T a, T b)
{
// Declare the parameters
var paramA = Expression.Parameter(typeof(T), "a");
var paramB = Expression.Parameter(typeof(T), "b");
// Add the parameters together
BinaryExpression body = Expression.Add(paramA, paramB);
// Compile it
Func<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
// Call it
return add(a, b);
}
This way you're creating a Func<T, T, T>
which performs the addition.
The full explanation can be found in this article.
Type T is not known by the compiler, so it cannot find an overloaded + operator defined anywhere...
The best you can currently do is declare your method as such (since all numeric types are convertible to double):
public static double Add (double number1, double number2)
{
return number1 + number2;
}
or if you're sure a suitable + operator will be defined:
public static T Add<T>(T number1, T number2)
{
dynamic dynamic1 = number1;
dynamic dynamic2 = number2;
return dynamic1 + dynamic2;
}
Updated
or a combination of the two:
public static T Add<T>(T in1, T in2)
{
var d1 = Convert.ToDouble(in1);
var d2 = Convert.ToDouble(in2);
return (T)(dynamic)(d1 + d2);
}
This is a problem that I just had when I wanted a generic method that could work on arbitrary lists of numbers, for example:
public T Calculate<T>(IEnumerable<T> numbers);
The solution I found was to use a lambda expression:
public T Calculate<T>(Func<T, T, T> add, IEnumerable<T> numbers);
Which you'd then call by
var sum = this.Calculate((a, b) => a + b, someListOfNumbers);
Obviously in some cases you may as well just have + inside the code instead of lambda expressions, but if you need to perform maths operations in a generic way this was the easiest thing I could come up with that is compile safe.
Since this is a generic type without a constraint the compiler has no knowledge if the types involved will have '+' overloaded hence the compiler error.
These are some workarounds:
public static TResult Add<T1, T2, TResult>(T1 left, T2 right, Func<T1, T2, TResult> AddMethod)
{
return AddMethod(left, right);
}
var finalLabel = Add("something", 3,(a,b) => a + b.ToString());
Below code lets you build but it's evaluated at run time so not runtime safe
public static T AddExpression<T>(T left, T right)
{
ParameterExpression leftOperand = Expression.Parameter(typeof(T), "left");
ParameterExpression rightOperand = Expression.Parameter(typeof(T), "right");
BinaryExpression body = Expression.Add(leftOperand, rightOperand);
Expression<Func<T, T, T>> adder = Expression.Lambda<Func<T, T, T>>(
body, leftOperand, rightOperand);
Func<T, T, T> theDelegate = adder.Compile();
return theDelegate(left, right);
}