Skip to content

Some code for generic operators implementation #729

@ebfortin

Description

@ebfortin

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();
	}

}

`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions