© 2026 Hedgehog Software, LLC

TwitterGitHubDiscord
More
CommunitiesDocsAboutTermsPrivacy
Search
Star
Setup for Free
C#C
C#•3y ago•
1 reply
InFarAday

❔ LINQ expressions with "pipeline" pattern

Basically I need to process an AST in multiple steps to generate a LINQ expression from it. To that end, I use a pipeline system that can extended at will. Each part of the pipeline is not coupled to any other but uses contract objects to communicate. For instance:
public class Part1 : IProcessor
{
  // DI properties and constructor

  public void Invoke()
  {
    // do something
    this.Part1Result.Result = x;
  }
}

public class Part1Result
{
  public Something Result {get;}

  public implicit operator Something(Part1Result wrapper) => wrapper.Result;
  //...
}
public class Part1 : IProcessor
{
  // DI properties and constructor

  public void Invoke()
  {
    // do something
    this.Part1Result.Result = x;
  }
}

public class Part1Result
{
  public Something Result {get;}

  public implicit operator Something(Part1Result wrapper) => wrapper.Result;
  //...
}


And then in a later processor:
public class Part2 : IProcessor
{
  public Part1Result PreviousResult {get;}

  public Part2(Part1Result p1result)
  {
    PreviousResult = p1result;
  }

  public void Invoke()
  {
    //...
  }
}
public class Part2 : IProcessor
{
  public Part1Result PreviousResult {get;}

  public Part2(Part1Result p1result)
  {
    PreviousResult = p1result;
  }

  public void Invoke()
  {
    //...
  }
}


My main problem comes from the fact that LINQ expressions are built with the more nested elements first. In my case though I need to build the expression beginning by the end. For instance, in the expression
Expression.Call(..., root, x, y, z);
Expression.Call(..., root, x, y, z);
I will only know
root
root
at the end of the pipeline. But I can't build the actual expression since if I don't know root I can't use Expression.Call on it.
What I did so far to solve this issue was add delegates in my results, like this:
public void Invoke()
{
  Expression something = ...;

  ResultWrapper.Result = root => Expression.Call(method, root, something);
}
public void Invoke()
{
  Expression something = ...;

  ResultWrapper.Result = root => Expression.Call(method, root, something);
}


And then the later part of the pipeline calls the delegate. This means that it will be the absolute last part of the pipeline that will end up doing all of the work. This works fine but performance concerns aside (because so many variables will be captured) I don't think it's a very sound design pattern.

What do you think?
C# banner
C#Join
We are a programming server aimed at coders discussing everything related to C# (CSharp) and .NET.
61,871Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

Build ref return with System.Linq.Expressions
C#CC# / help
4y ago
❔ System.Linq.Expressions custom expression
C#CC# / help
3y ago
I need help with understanding the flow of LINQ query expressions
C#CC# / help
3y ago
Why is this Linq.Expressions.Expression is evaluating to NULL?
C#CC# / help
2y ago