Search code examples
c#.net-generic-math

Resolving Operator '+' cannot be applied to operand of type 'T' and 'T'


I'm trying create a generic calculator class which can support arithmetic operations like add , sub & mul very basic. but I'm getting this below mentioned error. I'm getting a feel that I need to add generic constraint on 'T' to allow operation only on those type which support + operator. But not able to figure out the solution. Would be great help, if you can provide great explanation that will help me understand this fundamental part of it.

"Operator '+' cannot be applied to operands of type 'T' and 'T'

Here is the code for add operation. please let suggest the resolution to fix this problem.

**//this approach works** 
using System.Numerics;
namespace dotnet_basic;
public class Calculator
{
    public T Add<T>(T num1, T num2)
      where T : INumber<T> => num1 + num2;

    public T Subtract<T>(T num1, T num2)
        where T : INumber<T> => num2 - num1;
}


**//Corrected the second approach now even this approach works**
namespace dotnet_basic;
public class CalculatorNew<T> where T : INumber<T>
{

    public T Add(T num1, T num2)
    {
        return num1 + num2;
    }

}

Need to find out how this functionality can be achieved using the .net 6 or less than version 6. Once we have that answer this question can be closed.

Here is the code for achieving above mention functionality in .net 6 or less than version 6.

// solution from @peet
namespace dotnet_basic
{
    public class Calculator<T> where T : struct // Add constraint here, e.g., 'struct' for value types
    {
        public static T Add(T num1, T num2)
        {
            dynamic dynamicNum1 = num1;
            dynamic dynamicNum2 = num2;
            return dynamicNum1 + dynamicNum2;
        } 
    }
}

Solution

  • Since .NET 7 you can use the generic math interfaces:

    public class Calculator<T>
        where T : IAdditionOperators<T,T,T>
    {
        public static T Add(T num1, T num2)
        {
            return num1 + num2;
        }
    }
    

    Before .NET 7 the classic approach is building an expression:

    public class Calculator<T>
    {
        private static Func<T, T, T> _add;
    
        static Calculator()
        {
            var left = Expression.Parameter(typeof(T));
            var right = Expression.Parameter(typeof(T));
            _add  = Expression.Lambda<Func<T,T,T>> (
                    Expression.Add(left, right),
                    new ParameterExpression[] { left, right }
                ).Compile();
        }
        
        public static T Add(T num1, T num2)
        {
            return _add(num1, num2);
        }
    }