You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here's some code I'm using on another library I'm working on. It allows for arithmetic operations on generic types. Very useful for having operators applied to generic type. It doesn't allow the use of the actual operator, but it allows to avoid the "operator + not defined for generic type T" error. And it provides more performance than having the need to implement an IOperators interface.
Only drawback : depending on the type T used to instantiate the generic class, you may get a RuntimeError instead of catching it at compile time. I think it's still worth it.
`
public class Operators<T>
{
public static Func<T, T, T> Add = GenerateAdditionExpression();
public static Func<T, T, T> Sub = GenerateSubtractExpression();
public static Func<T, T, T> Mul = GenerateMultiplyExpression();
public static Func<T, T, T> Div = GenerateDivideExpression();
private static Func<T, T, T> GenerateAdditionExpression()
{
var l = Expression.Parameter(typeof(T));
var r = Expression.Parameter(typeof(T));
var add = Expression.Add(l, r);
return Expression.Lambda<Func<T, T, T>>(add, l, r).Compile();
}
private static Func<T, T, T> GenerateSubtractExpression()
{
var l = Expression.Parameter(typeof(T));
var r = Expression.Parameter(typeof(T));
var add = Expression.Subtract(l, r);
return Expression.Lambda<Func<T, T, T>>(add, l, r).Compile();
}
private static Func<T, T, T> GenerateMultiplyExpression()
{
var l = Expression.Parameter(typeof(T));
var r = Expression.Parameter(typeof(T));
var add = Expression.Multiply(l, r);
return Expression.Lambda<Func<T, T, T>>(add, l, r).Compile();
}
private static Func<T, T, T> GenerateDivideExpression()
{
var l = Expression.Parameter(typeof(T));
var r = Expression.Parameter(typeof(T));
var add = Expression.Divide(l, r);
return Expression.Lambda<Func<T, T, T>>(add, l, r).Compile();
}
}
`
I also have a class for casting. Same drawback as for aithmetics ones : you'll get the error at runtime, not compile time, if the type can't be casted to the specified one.
`
public class CastOperators<T, U>
{
public static Func<T, U> Cast = GenerateCastExpression();
private static Func<T, U> GenerateCastExpression()
{
var l = Expression.Parameter(typeof(T));
var cast = Expression.Convert(l, typeof(U));
return Expression.Lambda<Func<T, U>>(cast, l).Compile();
}
}
`
The text was updated successfully, but these errors were encountered:
Thanks for posting. As you mention, we have discussed something similar before in #666 and #695, using runtime compilation to allow for performant arithmetic with different numeric types.
Here's some code I'm using on another library I'm working on. It allows for arithmetic operations on generic types. Very useful for having operators applied to generic type. It doesn't allow the use of the actual operator, but it allows to avoid the "operator + not defined for generic type T" error. And it provides more performance than having the need to implement an IOperators interface.
Only drawback : depending on the type T used to instantiate the generic class, you may get a RuntimeError instead of catching it at compile time. I think it's still worth it.
`
`
I also have a class for casting. Same drawback as for aithmetics ones : you'll get the error at runtime, not compile time, if the type can't be casted to the specified one.
`
`
The text was updated successfully, but these errors were encountered: