Skip to content

Commit

Permalink
Lazy compile expression in Lambda (#219)
Browse files Browse the repository at this point in the history
Lazy compile expression in Lambda class to avoid compilation when is not needed.
  • Loading branch information
ealeykin authored Dec 23, 2021
1 parent 08404b3 commit 1d01401
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 14 deletions.
22 changes: 8 additions & 14 deletions src/DynamicExpresso.Core/Lambda.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,22 @@ public class Lambda
{
private readonly Expression _expression;
private readonly ParserArguments _parserArguments;

private readonly Delegate _delegate;
private readonly Lazy<Delegate> _delegate;

internal Lambda(Expression expression, ParserArguments parserArguments)
{
if (expression == null)
throw new ArgumentNullException("expression");
if (parserArguments == null)
throw new ArgumentNullException("parserArguments");

_expression = expression;
_parserArguments = parserArguments;
_expression = expression ?? throw new ArgumentNullException(nameof(expression));
_parserArguments = parserArguments ?? throw new ArgumentNullException(nameof(parserArguments));

// Note: I always compile the generic lambda. Maybe in the future this can be a setting because if I generate a typed delegate this compilation is not required.
var lambdaExpression = Expression.Lambda(_expression, _parserArguments.UsedParameters.Select(p => p.Expression).ToArray());
_delegate = lambdaExpression.Compile();
// Note: I always lazy compile the generic lambda. Maybe in the future this can be a setting because if I generate a typed delegate this compilation is not required.
_delegate = new Lazy<Delegate>(() =>
Expression.Lambda(_expression, _parserArguments.UsedParameters.Select(p => p.Expression).ToArray()).Compile());
}

public Expression Expression { get { return _expression; } }
public bool CaseInsensitive { get { return _parserArguments.Settings.CaseInsensitive; } }
public string ExpressionText { get { return _parserArguments.ExpressionText; } }
public Type ReturnType { get { return _delegate.Method.ReturnType; } }
public Type ReturnType { get { return Expression.Type; } }

/// <summary>
/// Gets the parameters actually used in the expression parsed.
Expand Down Expand Up @@ -112,7 +106,7 @@ private object InvokeWithUsedParameters(object[] orderedArgs)
{
try
{
return _delegate.DynamicInvoke(orderedArgs);
return _delegate.Value.DynamicInvoke(orderedArgs);
}
catch (TargetInvocationException exc)
{
Expand Down
5 changes: 5 additions & 0 deletions src/DynamicExpresso.Core/Parameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public Parameter(string name, Type type, object value = null)
Expression = System.Linq.Expressions.Expression.Parameter(type, name);
}

public static Parameter Create<T>(string name, T value)
{
return new Parameter(name, typeof(T), value);
}

public string Name { get; private set; }
public Type Type { get; private set; }
public object Value { get; private set; }
Expand Down

0 comments on commit 1d01401

Please sign in to comment.