StaticOperatorProxy.cs
Home
/
ExpressionOperatorProxy /
ExpressionOperatorProxy /
Generic /
MathOperatorProxy /
StaticOperatorProxy.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;
namespace ExpressionOperatorProxy.Generic.MathOperatorProxy
{
/// <summary>
/// Пример реализации взят с
/// http://www.cyberforum.ru/csharp-net/thread1994108.html
///
/// Позволяет производить арифметические операции над Generic T типом
/// Возможны ошибки, если используемый тип не реализует используемую операцию
/// Список операций можно расширить на основе возможностей класса Expression
/// </summary>
/// <typeparam name="T"></typeparam>
public static class StaticOperatorProxy<T>
{
private readonly static Func<T, T, T> _addOperator;
private readonly static Func<T, T, T> _subtractOperator;
private readonly static Func<T, T, T> _multiplyOperator;
private readonly static Func<T, T, T> _divideOperator;
private static Func<T, T, T> CreateDelegate(BinaryExpression expression, ParameterExpression parameter1, ParameterExpression parameter2)
{
return Expression
.Lambda<Func<T, T, T>>(
expression,
new[]
{
parameter1,
parameter2
}
).Compile();
}
static StaticOperatorProxy()
{
var operand1 = Expression.Parameter(typeof(T), "o1");
var operand2 = Expression.Parameter(typeof(T), "o2");
var addCall = Expression.Add(operand1, operand2);
var subtractCall = Expression.Subtract(operand1, operand2);
var multiplyCall = Expression.Multiply(operand1, operand2);
var dividetractCall = Expression.Divide(operand1, operand2);
_addOperator = CreateDelegate(addCall, operand1, operand2);
_subtractOperator = CreateDelegate(subtractCall, operand1, operand2);
_multiplyOperator = CreateDelegate(multiplyCall, operand1, operand2);
_divideOperator = CreateDelegate(dividetractCall, operand1, operand2);
}
public static T Add(T operand1, T operand2)
{
return _addOperator(operand1, operand2);
}
public static T Subtract(T operand1, T operand2)
{
return _subtractOperator(operand1, operand2);
}
public static T Multiply(T operand1, T operand2)
{
return _multiplyOperator(operand1, operand2);
}
public static T Divide(T operand1, T operand2)
{
return _divideOperator(operand1, operand2);
}
}
}