Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private methods vs local functions

Tags:

c#

c#-7.0

To my understanding, both local functions and private methods serve merely as implementation details - helpers for public methods. Why would I want to choose one over the other?

When using a private method, I create a semantic relation between the object and the method (although not seen from the outside), which is not always justified. That is why my first instinct is that local functions are the way to go unless more than one public method uses it, in which case I would go with private methods.

But are there any objective reasons to favor one of them? Are there any situations where one is preferable over the other? What are the pros and cons of using any of them?

like image 697
Michael Haddad Avatar asked Feb 09 '20 14:02

Michael Haddad


People also ask

When should you use private methods?

Private methods are useful for breaking tasks up into smaller parts, or for preventing duplication of code which is needed often by other methods in a class, but should not be called outside of that class.

What are local functions?

Local functions are methods of a type that are nested in another member. They can only be called from their containing member. Local functions can be declared in and called from: Methods, especially iterator methods and async methods. Constructors.

Should my methods be public or private?

Generally you should expose as little as possible and make everything private that is possible. If you make a mistake and hide something you should be exposing, no problem, just make it public.

What is the purpose of making a private function?

Private functions are defined as “a means of gathering individuals for the purpose of deliberation, education, instruction, entertainment, amusement, or dining, where specific invitation is a prerequisite to entry and where the event is not intended to be open to the public.” Houston, Tex., Ordinance 2006-1054 art.


2 Answers

It is all about code readability. Looking at the motivation of local function

Local functions make the intent of your code clear. Anyone reading your code can see that the method is not callable except by the containing method. For team projects, they also make it impossible for another developer to mistakenly call the method directly from elsewhere in the class or struct.

the main reason for local function is to give the intent: This code is only for this method; do not reuse it from other places. Stated otherwise: Private methods signal their potential reuse from other class methods.

There are some more use cases behind this language feature as discussed in the Roslyn-Rep here.:

  • It is very common to write a helper method that is only used from one place, but it makes the code less clear to the reader because the association between the helper function and the thing it is helping is not explicit. Local functions makes the association part of the syntax.
  • An iterator method that validates its arguments (write a non-iterator function to validate the arguments, and then return the result of invoking a local iterator function)
  • A Task-returning method that has no async machinery in the common case where it doesn't need to "go async"
  • You are writing a method that returns an array, but want the syntactic convenience of the iterator method syntax (yield return).

These use cases are explained in the Blog Post https://devblogs.microsoft.com/premier-developer/dissecting-the-local-functions-in-c-7/

like image 117
Ralf Bönning Avatar answered Sep 17 '22 18:09

Ralf Bönning


Sometimes logic is huge and contains many repetitions, such as ...

public void ValidateCustomer(Customer customer){

  if( string.IsNullOrEmpty( customer.FirstName )){
       string error = "Firstname cannot be empty";
       customer.ValidationErrors.Add(error);
       ErrorLogger.Log(error);
       throw new ValidationError(error);
  }

  if( string.IsNullOrEmpty( customer.LastName )){
       string error = "Lastname cannot be empty";
       customer.ValidationErrors.Add(error);
       ErrorLogger.Log(error);
       throw new ValidationError(error);
  }

  ... on  and on... 
}

Such repetition can be replaced with local function,

  public void ValidateCustomer(Customer customer){

      void _validate(string value, string error){
           if(!string.IsNullOrWhitespace(value)){

              // i can easily reference customer here
              customer.ValidationErrors.Add(error);

              ErrorLogger.Log(error);
              throw new ValidationError(error);                   
           }
      }

      _validate(customer.FirstName, "Firstname cannot be empty");
      _validate(customer.LastName, "Lastname cannot be empty");
      ... on  and on... 
  }

If you look closely, you don't have to pass parameters to local function as they can reference everything in enclosing function, you have to only pass changed parameters. If you write private methods, you will have to pass many number of parameters.

like image 45
Akash Kava Avatar answered Sep 16 '22 18:09

Akash Kava