: ExpressionVisitor
where TFilterable : ICanBeFiltered
where TFilterType : IAmAFilter
… override
VisitParameter
…
protected override Expression VisitParameter(ParameterExpression node) =>
ReferenceEquals(replacing, node)
?
replacement
: base.VisitParameter(node);
… and override
VisitLambda
…
protected override Expression VisitLambda(Expression node)
… and inside it define the creation of a new instance of the filter …
var newFilterType = Expression.New
(
_filterTypeCtor,
replacement
);
… then we declare a variable to hold the instance of the filter …
var filterInstance = Expression.Variable(typeof(TFilterType), "filterTypeInstance");
… replace the inner filter parameter with the newly created filter instance parameter …
var visitor = new RewriteFilterTypeExpression(node.Parameters.Single(), filterInstance);
var replaced = visitor.Visit(node) as LambdaExpression;
… and then finally create a
BlockExpression
to wrap this together and return the result of the original expression …
return Expression.Block
(
new[] { filterInstance },
Expression.Assign(filterInstance, newFilterType),
Expression.Condition
(
replaced.Body,
Expression.Constant(true),
Expression.Constant(false)
)
);
The expression block can now be logically combined with the first expression, as now both expect the same input type. Then the resulting expression would look similar to this:
Lambda1(Com.Example.SomeClassToBeFiltered $e)
{
$e.Property1 >= 42 && .Block(Com.Example.MagicFilter $filterTypeInstance)
{
$filterTypeInstance = .New Com.Example.MagicFilter($e);
.If (
(System.Boolean)$filterTypeInstance.IsPresent == True &&
(System.Boolean)$filterTypeInstance.ItemsAvailable > 0
) {
True
} .Else {
False
}
}
}
Once again, with the power of expressions, it is possible to achieve the seemingly impossible …
I am a senior auditor and consultant at d-fens for business processes and information systems.
Post navigation
Search for...
Search
Using EntityFramework with Sqlite InMemory, DbConcurrency and Migrations
Combining Expression[Func[T, bool]] of different Types
Testing in Python – My first steps with pytest
[HOWTO] Create Model Document using Sparx Enterprise Architect API
[Bug] Sparx Enterprise Architect v14.1 Build 1429 not triggering EA_OnPostCloseDiagram event in context of Time Aware Modelling