dopplesoldner
dopplesoldner

Reputation: 9499

c# generic method for mathematical operations

I would like to create a generic method which performs basic mathematical operations. For eg. If a double is passed to the function, it will return double.

public static T Multiply<T> (T A, int B)
{
   //some calculation here
   return (T) A * B; 
}

This doesn't work for me.

EDIT: I get an error Operator '*' cannot be applied to operands of type 'T' and 'int'

However I am wondering if there are other ways to achieve what I am trying to?

Thanks

Upvotes: 3

Views: 2987

Answers (5)

Frederik van Lierde
Frederik van Lierde

Reputation: 66

You should add Dynamic in front of the A and the conversion to T must be done on the full calculation

public static T Multiply<T>(T A, int B)
{
   return (T)((dynamic)A * B);
}

Upvotes: 0

FlintZA
FlintZA

Reputation: 872

Being stuck on an on older .Net version, without access to dynamic, I have a very simple class that does very much what you're looking for, and allows for use of actual operators: Numeric It may be worth a look on current .Net as well.

Method declaration:

public static T LerpMinMax<T>(Numeric<T> input, Numeric<T> inputMin, Numeric<T> inputMax, Numeric<T> outputMin, Numeric<T> outputMax)
{
     if (input <= inputMin)
     {
        return outputMin;
     }
     else if (input >= inputMax)
     {
        return outputMax;
     }
     return outputMin + ((input - inputMin) / (inputMax - inputMin)) * (outputMax - outputMin);
}

And then use:

float lerp = LerpMinMax<float>(0.55f, 0.0f, 0.1f, 0.0f, 1000.0f);

It's definitely not as flexible as MiscUtil's Operator, but was intended to be simple and (relatively) fast. It's still significantly slower than using operations directly (say by using T4 templates that spit out non-generic type-specific implementations) but used in the above way it's equivalent to MiscUtil's Operator class. It also obviously has the benefit of generally more readable algorithm implementations, and can support custom classes that implement operators.

Upvotes: 0

Jim Lahman
Jim Lahman

Reputation: 2767

Here's my example for using generics to compare to numbers:

    public bool TIsEqual<T>(T f1, T f2, T margin)
    {
        T diff = default(T);
        T error = default(T);
        diff = Math.Abs((dynamic)f1 - f2);
        error = (dynamic)margin * f1;
        return (dynamic) diff < error;
    }

Upvotes: -1

jltrem
jltrem

Reputation: 12544

This is the simplest to implement, but is not efficient:

  public static T Multiply<T>(T A, int B)
  {
     T val = default(T);
     try
     {
        val = (dynamic)A * B;
     }
     catch
     { }

     return val;
  }

Depending on your needs it might be fine for you. You may consider not handling the exception in the method, or using an out value so that you can return both the answer and a success value.

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727077

You can do it by constructing and compiling a LINQ expression for the specific type, like this:

private static IDictionary<Type,object> MultByType = new Dictionary<Type,object>();
public static T Multiply<T>(T a, int b) {
    Func<T,int,T> mult;
    object tmp;
    if (!MultByType.TryGetValue(typeof (T), out tmp)) {
        var lhs = Expression.Parameter(typeof(T));
        var rhs = Expression.Parameter(typeof(int));
        mult = (Func<T,int,T>) Expression.Lambda(
            Expression.Multiply(lhs, Expression.Convert(rhs, typeof(T)))
        ,   lhs
        ,   rhs
        ).Compile();
        MultByType.Add(typeof(T), mult);
    } else {
        mult = (Func<T,int,T>)tmp;
    }
    return mult(a, b);
}

To avoid recompiling the expression each time it is used, one could cache it in a dictionary.

Note that this approach has certain limitations:

  • Multiplication of T by T is expected to be defined,
  • The output of multiplication is expected to be T without conversion. This is not true for types smaller than int,
  • The type must support conversion from int.

None of this is checked at compile time.

Upvotes: 2

Related Questions