The release of C# 7 brought a lot of useful features and constructors and one of that are the local functions. Before of these, when we had to provide a functionality to a class method we had to use a private class method and than call it. This is a common approach but in some cases this private method could be called only from one public method, so the private function was elevated to a private class method even if it’s referenced from a single point.
Of course previously of C# 7 we had no choice but now with the local functions things are changed.
Details
Suppose that I have a class method that deal with the parsing of a tree nodes. The method will accept a node as a parameter and the node class looks like this:
public class Node { public int Id { get; set; } public string Name { get; set; } public Node Parent { get; set; } }
The first operation of the method will be build the list of nodes (the node itself and the parent nodes) then the method will return all the nodes which the name contains “hr”:
public List<Node> NodesProcessing(Node node) { var nodes = new List<Node>(); var currentNode = node; while (node != null) { nodes.Add(currentNode); currentNode = node.Parent; } return nodes.Where(n => n.Name.Contains("hr")).ToList(); }
With local functions we can write the method better:
public List<Node> NodesProcessing(Node node) { return GetNodeList().Where(n => n.Name.Contains("hr")).ToList(); IEnumerable<Node> GetNodeList() { while (node != null) { yield return node; node = node.Parent; } } }
The scope of the function will be the parent method, this means that other methods will not be able to access to that. You can look to the local function as a closure, that is a function with rights to access to the variable contained in the parent scope.
Effectively you can see that the GetNodeList function use the node parameter without the parent method passed it. Moreover with this function we have solved the problem that we cannot use iterators in lambda functions, that is an example of the application fields of local functions. They can be async as well, so we can use statements that concerns IO operations and so on.
Generally local functions makes our code cleaner and more testable and we can use them when we notice they could simplify the code.
MSIL
How the compiler translate these function in IL? This question could appear trivial but the response will be very surprendent. As they are closures, if they not use referenced types, they will be translated in static methods, that means better performances compared to common lambda expressions.
So this is an aspect that we could take in consideration where we choose between local functions and lambda expressions. In case of high performances applications this is a very important aspect.
Summary
We have seen what are the local functions, a new functionality of C# 7. They are useful for write better code and improving perfomance for high performance applications, because they are translated in static methods.
We can use these to solve different problems like objects iterations and they supports async operations as well.
Leave a Reply