Skip to content

Commit e2c8c20

Browse files
committed
On the fly parameter cast
1 parent dc5d765 commit e2c8c20

File tree

3 files changed

+104
-1
lines changed

3 files changed

+104
-1
lines changed

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,32 @@ private void Evaluator_EvaluateVariable(object sender, VariableEvaluationEventAr
12771277
}
12781278
}
12791279

1280+
[TestCase("ClassForTest1.Add(1, 5)", ExpectedResult = 6, Category = "On the fly method")]
1281+
[TestCase("ClassForTest1.Add(1, 5.0)", ExpectedResult = 6, Category = "On the fly method")]
1282+
public object OnTheFlyEvaluation2(string expression)
1283+
{
1284+
ExpressionEvaluator evaluator = new ExpressionEvaluator(new ContextObject1());
1285+
1286+
evaluator.EvaluateParameterCast += Evaluator_EvaluateParameterCast;
1287+
1288+
evaluator.Namespaces.Add("CodingSeb.ExpressionEvaluator.Tests");
1289+
1290+
return evaluator.Evaluate(expression);
1291+
}
1292+
1293+
private void Evaluator_EvaluateParameterCast(object sender, ParameterCastEvaluationEventArg e)
1294+
{
1295+
if (e.ParameterType == typeof(ClassForTest2) && e.OriginalArg is int originalArgInt)
1296+
{
1297+
e.Argument = new ClassForTest2(originalArgInt);
1298+
}
1299+
1300+
if (e.ParameterType == typeof(ClassForTest2) && e.OriginalArg is double originalArgDouble)
1301+
{
1302+
e.Argument = new ClassForTest2((int) originalArgDouble);
1303+
}
1304+
}
1305+
12801306
#endregion
12811307

12821308
#endregion

CodingSeb.ExpressionEvaluator.Tests/TestsUtils/ClassForTest1.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,10 @@ public static string StaticStringMethod(string Name)
2626

2727
public Func<int, int, int> AddAsDelegate { get; set; } = (nb1, nb2) => nb1 + nb2;
2828
public static Func<int, int, int> AddAsStaticDelegate { get; set; } = (nb1, nb2) => nb1 + nb2;
29+
30+
public static int Add(int a, ClassForTest2 b)
31+
{
32+
return a + b.Value1;
33+
}
2934
}
3035
}

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,12 @@ public IDictionary<string, object> Variables
952952
/// </summary>
953953
public event EventHandler<FunctionEvaluationEventArg> EvaluateFunction;
954954

955+
/// <summary>
956+
/// Is fired when a parameter ist not the correct type for the function.
957+
/// Allow to define a custom parameter cast for the function to work on the fly.
958+
/// </summary>
959+
public event EventHandler<ParameterCastEvaluationEventArg> EvaluateParameterCast;
960+
955961
#endregion
956962

957963
#region Constructors and overridable Inits methods
@@ -3333,7 +3339,25 @@ protected virtual MethodInfo TryToCastMethodParametersToMakeItCallable(MethodInf
33333339
}
33343340
catch
33353341
{
3336-
parametersCastOK = false;
3342+
try
3343+
{
3344+
ParameterCastEvaluationEventArg parameterCastEvaluationEventArg =
3345+
new ParameterCastEvaluationEventArg(parameterType, modifiedArgs[a]);
3346+
EvaluateParameterCast.Invoke(this, parameterCastEvaluationEventArg);
3347+
if (parameterCastEvaluationEventArg.FunctionModifiedArgument)
3348+
{
3349+
modifiedArgs[a] = parameterCastEvaluationEventArg.Argument;
3350+
}
3351+
else
3352+
{
3353+
parametersCastOK = false;
3354+
}
3355+
}
3356+
catch
3357+
{
3358+
parametersCastOK = false;
3359+
}
3360+
33373361
}
33383362
}
33393363
}
@@ -4377,5 +4401,53 @@ public FunctionPreEvaluationEventArg(string name, Func<string, object> evaluateF
43774401
public bool CancelEvaluation { get; set; }
43784402
}
43794403

4404+
/// <summary>
4405+
/// Class ParameterCastEvaluationEventArg.
4406+
/// Implements the <see cref="System.EventArgs" /></summary>
4407+
/// <seealso cref="System.EventArgs" />
4408+
public partial class ParameterCastEvaluationEventArg : EventArgs
4409+
{
4410+
/// <summary>
4411+
/// The required type of the parameter
4412+
/// </summary>
4413+
public Type ParameterType { get; }
4414+
4415+
/// <summary>
4416+
/// The original argument
4417+
/// </summary>
4418+
public object OriginalArg { get; }
4419+
4420+
/// <summary>
4421+
/// Initializes a new instance of the <see cref="ParameterCastEvaluationEventArg" /> class.
4422+
/// </summary>
4423+
/// <param name="parameterType">Type of the parameter.</param>
4424+
/// <param name="originalArg">The original argument.</param>
4425+
public ParameterCastEvaluationEventArg(Type parameterType, object originalArg)
4426+
{
4427+
ParameterType = parameterType;
4428+
OriginalArg = originalArg;
4429+
}
4430+
4431+
private object modifiedArgument;
4432+
4433+
/// <summary>
4434+
/// To set the modified argument
4435+
/// </summary>
4436+
public object Argument
4437+
{
4438+
get { return modifiedArgument; }
4439+
set
4440+
{
4441+
modifiedArgument = value;
4442+
FunctionModifiedArgument = true;
4443+
}
4444+
}
4445+
4446+
/// <summary>
4447+
/// if <c>true</c> the argument has been modified, if <c>false</c> it means that the argument can't be of the given type.
4448+
/// </summary>
4449+
public bool FunctionModifiedArgument { get; set; }
4450+
}
4451+
43804452
#endregion
43814453
}

0 commit comments

Comments
 (0)