Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Adding two Generic Values

Can someone explain why this won't work? I was trying to be able to add two values regardless of the numeric type.

public static T Add<T> (T number1, T number2)
{
    return number1 + number2;
}

When I compile this, I get the following error:

Operator '+' cannot be applied to operands of type 'T' and 'T'
like image 892
Andy Evans Avatar asked Nov 14 '11 13:11

Andy Evans


3 Answers

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.

like image 183
Darin Dimitrov Avatar answered Oct 11 '22 02:10

Darin Dimitrov


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.

like image 31
Adi Lester Avatar answered Oct 11 '22 01:10

Adi Lester


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);
}
like image 45
Rich O'Kelly Avatar answered Oct 11 '22 00:10

Rich O'Kelly