So, I did Linq.Expressions (and if someone can suggest a more correct or more elegant way of doing what I do, feel free to call) and hit the wall trying to do something,
Suppose we have a simple math class:
public class SimpleMath {
public int AddNumbers(int number1, int number2) {
return number1 + number2;
}
}
I decided that I want to convert our method AddNumbersto a simple delegate Func<object, object, object>.
To do this, I do the following:
List<ParameterExpression> parameters = new List<ParameterExpression>();
List<Expression> convertedParameters = new List<Expression>();
ParameterExpression parameter1 = Expression.Parameter(typeof(object));
parameters.Add(parameter1);
convertedParameters.Add(Expression.Convert(parameter1, typeof(int)));
ParameterExpression parameter2 = Expression.Parameter(typeof(object));
parameters.Add(parameter2);
convertedParameters.Add(Expression.Convert(parameter2, typeof(int)));
SimpleMath simpleMath = new SimpleMath();
MethodInfo addNumebrsMethodInfo = simpleMath.GetType().GetMethods().Where(x => x.Name == "AddNumbers").ToArray()[0];
MethodCallExpression returnMethodWithParameters = Expression.Call(Expression.Constant(simpleMath), addNumebrsMethodInfo, convertedParameters);
UnaryExpression returnMethodWithParametersAsObject = Expression.Convert(returnMethodWithParameters, typeof(object));
Func<object, object, object> func = Expression.Lambda<Func<object, object, object>>(returnMethodWithParametersAsObject, parameters).Compile();
object result = func(20, 40);
So, if you run this code func, you need to return simple calculations. However, it accepts Type Object parameters, which obviously leave it open to run-time problems, for example:
object result1 = func(20, "f");
, Try...Catch (, , AddNumbers ).
, , :
TryExpression tryCatchMethod = TryExpression.TryCatch(returnMethodWithParametersAsObject, Expression.Catch(typeof(InvalidCastException), Expression.Constant(55, typeof(object))));
Func<object, object, object> func = Expression.Lambda<Func<object, object, object>>(tryCatchMethod, parameters).Compile();
object result = func(20, "f");
TryExpression.TryCatch , CatchBlock. returnMethodWithParametersAsObject - , , Expression.Catch , , , InvalidCastException, - , 55.
, , , . , SimpleMath, HandleException:
public class SimpleMath {
public int AddNumbers(int number1, int number2) {
return number1 + number2;
}
public int HandleException() {
return 100;
}
}
:
MethodInfo handleExceptionMethodInfo = simpleMath.GetType().GetMethods().Where(x => x.Name == "HandleException").ToArray()[0];
MethodCallExpression returnMethodWithParameters2 = Expression.Call(Expression.Constant(simpleMath), handleExceptionMethodInfo);
UnaryExpression returnMethodWithParametersAsObject2 = Expression.Convert(returnMethodWithParameters2, typeof(object));
, TryCatch:
TryExpression tryCatchMethod2 = TryExpression.TryCatch(returnMethodWithParametersAsObject, Expression.Catch(typeof(InvalidCastException), returnMethodWithParametersAsObject2));
Func<object, object, object> func = Expression.Lambda<Func<object, object, object>>(tryCatchMethod2, parameters).Compile();
object result = func(20, "f");
, InvalidCastException SimpleMath.HandleException. , , .
Try... Catch block . .
try {
} catch (InvalidCastException ex) {
}
, , , , Try... Catch.
!
p.s. , , , , , .