Lambda Expressions and Delegates

Lambda expressions in Java translate quite easily to lambda expressions in C#: apart from the use of a different arrow symbol, the rules are very similar.

I've already mentioned that the JavaParser symbol solver struggles a bit with type inference inside lambda expressions, and we sometimes need to provide a bit of assistance by declaring types explicitly.

The main problem, however, is that Java is much more flexible than C# about where lambda expressions are allowed to appear. To take an example, we have a method NodeInfo.iterateAxis(Axis, NodeTest). On the Java side, NodeTest is a functional interface, which means the caller can either supply a lambda expression such as node -> node.getURI() == null, or they can supply an instance of a class that implements the NodeTest interface, for example new LocalNameTest("foo"). In C# NodeTest must either be defined as a delegate, in which case the caller must supply a lambda expression and not an implementing class, or it can be defined as a regular interface, in which case they can supply an implementing class but not a lambda expression.

To solve this, in most cases we've kept it as an interface, but supplied an implementation of the interface that accepts a lambda expression. So if you want to use a lambda expression here, you have to write NodeTestLambda.of(node -> node.getURI() == null). Which is convoluted, but works.