Using C# 7 Local Functions

Over the years, I've created many classes where the number of methods used only by that class grew to quite a number, even though those methods were directly related to the purpose of the class. Even with comments, good naming, and other such devices, the class was increasingly difficult to understand at first glance.

It's also worth noting that, in several instances, those methods were only called by a single method elsewhere in the class; and, looking back at some of that code, this is a very true state of affairs.

So, does C#7 bring anything to help alleviate this problem? The answer to that question is yes! C# 7 will bring to us the use of local functions.

Consider the following scenario. Using MVVM, I have my view model which will make up a part of a UWP app. The View Model is ultimately the piece of the puzzle that glues everything together; a method could be responsible for gathering pre-processed data before displaying it on the view.

I might have some code that looks something like this…

class Program
{
   static IEnumerable<string> YAxis { get; set; }
   static IEnumerable<string> XAxis { get; set; }
   static IEnumerable<double> Data { get; set; }

   static void Main(string[] args)
   {
      GetData();
   }

   static void GetData()
   {
      YAxis = GetYAxisLabels();
      XAxis = GetXAxisLabels();
      Data = GetDataPoints();
   }

   static IEnumerable<string> GetYAxisLabels()
   {
      for(int i = 0; i < 10; i++)
      yield return $"YLabel {i}";
   }

   static IEnumerable<string> GetXAxisLabels()
   {
      for (int i = 0; i < 20; i++)
      yield return $"XLabel {i}";
   }

   static IEnumerable<double> GetDataPoints()
   {
      Random rand = new Random();
      for (int i = 0; i < 20; i++)
      yield return rand.NextDouble();
   }
}
Note: I'm using a console application to simulate how it might look in a more complicated UWP app, but we can see from this code the class could become quite long, where many of the methods are called from only one method. However, we are using those methods to separate out code and responsibility.

How might this look using local functions? Let's look at this next piece of code…

static void GetData()
{
   YAxis = getYAxisLabels();
   XAxis = getXAxisLabels();
   Data = getDataPoints();

   IEnumerable<string> getYAxisLabels()
   {
      for (int i = 0; i < 10; i++)
      yield return $"YLabel {i}";
   }

   IEnumerable<string> getXAxisLabels()
   {
      for (int i = 0; i < 20; i++)
      yield return $"XLabel {i}";
   }

   IEnumerable<double> getDataPoints()
   {
      Random rand = new Random();
      for (int i = 0; i < 20; i++)
      yield return rand.NextDouble();
   }
}

From the preceding code sample, the lines of code we used have haven't really changed, but, we can very quickly see that the local functions are directly related to the method in which they reside. This is one of the primary design concepts of local functions, and can allow us to very quickly understand a class, especially if it's one we are creating and others may need to understand it. Adding to this, we also can say that the local function cannot be accidentally called elsewhere in the class.

If you want to see some output from the previous code, I've added these few lines here…

YAxis = getYAxisLabels();
XAxis = getXAxisLabels();
Data = getDataPoints();

foreach(var d in Data)
   Console.WriteLine(d);

Which should give us an output like what is seen in Figure 1.

Output from our local functions example
Figure 1: Output from our local functions example

As I'm sure you've noticed, I've declared the local functions after they are called. With local functions, this is acceptable, and it's one of the features that separates local functions from lambdas.

Take this next code sample, for example…

static void RecursiveTest()
{
   Action printMessageDelegate = () => {
      Console.WriteLine("Delegae called");
   };

   printMessageDelegate();

   printMessageLocalFunction();

   void printMessageLocalFunction()
   {
      Console.WriteLine("Local function called");
   }
}

The printMessageDelegate must be defined before it is called; but, below that, we can see our local function working happily even though it was defined after its point of call. There are other differences between lambdas and local functions that may interest you, but the primary one is that of performance. If it can be done with a local function, you'll see the performance benefits where high performance code is required; you'll be rewarded for using them.

Conclusion

After speaking with a number of other developers, I've determined that local functions are a very welcome addition to the C# language, and one that I hope will assist your good self in your day to day code duties.

If you have any questions about this article, please find me on Twitter @GLanata.



About the Author

Gavin Lanata

Gavin has been building front-ends to software applications; desktop, web, and mobile, for several years now. Gavin often attends developer events, expanding his own knowledge in the fast paced world of IT, and lending a helping hand to developers needing a little direction navigating the world of design. Gavin has dedicated his time to the study of the many factors influencing human usage and reaction to software application. Art, design and coding name a few but certainly not the least of his tools to find the truths behind why we like and use the things we do.

Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date