8 Replies - 660 Views - Last Post: 01 June 2019 - 09:36 AM

#1 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6929
  • View blog
  • Posts: 23,551
  • Joined: 05-May 12

Any style recommendations for C# 7.0 local functions?

Posted 29 September 2018 - 06:00 PM

Does anybody have any recommendations regarding coding style when using C# 7.0 local functions?

I personally think that the feature is great, specially for the case when a few helper functions would make the code more legible, but I can also see how this feature can be easily abused. Although one of the intended results was the ability to do eager parameter checks and less hierarchical exceptions, I personally would also use it to make my parameter checks DRY-er by completely skipping parameter checks in my helper functions.

For my personal projects, I'm limiting myself to 60 lines for the containing function. That's about a screen height for my current monitor setup at home, and about a screen and a half on my laptop. As in the past, I still limit my local functions to no more than 25 lines. If I'm going over 60 lines or more than 5 local functions, it might be a code smell for me to create a whole new class whose single responsibility matches the work of the big function. My local functions should be readily understandable. If I need to comment a local function, then it's definitely a code smell that I'm doing something wrong and need to rethink my approach.

Does anybody else use local functions? What style rules do you use? Or if you don't use them currently, but are planning on doing so, what rules do you think you'll be using?

Is This A Good Question/Topic? 0
  • +

Replies To: Any style recommendations for C# 7.0 local functions?

#2 modi123_1   User is offline

  • Suitor #2
  • member icon



Reputation: 15080
  • View blog
  • Posts: 60,226
  • Joined: 12-June 08

Re: Any style recommendations for C# 7.0 local functions?

Posted 29 September 2018 - 07:09 PM

I looked at them, and raised an eyebrow. They look good in theory, but fall on the "well, shit.. these could be abused". Haven't had a good reason to implement them yet, but would be interested if anyone has.
Was This Post Helpful? 0
  • +
  • -

#3 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6929
  • View blog
  • Posts: 23,551
  • Joined: 05-May 12

Re: Any style recommendations for C# 7.0 local functions?

Posted 09 October 2018 - 01:54 PM

Something I've found myself doing at work lately...
class Foo
{
    public SomeResult DoWork(int foo, int bar)
    {
        try
        {
            return DoIt();
        }

        catch (Exception ex)
        {
            Log.Error(ex);
            throw;
        }

        SomeResult DoIt()
        {
            // do the work that may potentially fail and we simply want to log and then bubble up
        }
    }
}



which seems to have more encapsulation and less verbose than what I used to do in the past:
class Foo
{
    public SomeResult DoWork(int foo, int bar)
    {
        try
        {
            return DoWorkReally(foo, bar);
        }

        catch (Exception ex)
        {
            Log.Error(ex);
            throw;
        }
    }

    private SomeResult DoWorkReally(int foo, int bar)
    {
        // do the work that may potentially fail and we simply want to log and then bubble up
    }
}


Was This Post Helpful? 0
  • +
  • -

#4 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7434
  • View blog
  • Posts: 15,411
  • Joined: 16-October 07

Re: Any style recommendations for C# 7.0 local functions?

Posted 10 October 2018 - 05:34 AM

I meant to respond to this before. I do enjoy the local function thing. Any time I can reduce the scope of code, I'm happy.
Additionally, I find the ability to put the code at the end makes for a much cleaner block. ( It's a lot like how I write some Javascript. )

I find this is much nicer to read:
IEnumerable<Thing> GetThings() {
    return GetDifferentThings().Select(ToThing);
    Thing ToThing(OtherThing x) {
        //...
    }
}



Yes, I can use a lambda, but sometimes typing the beast early is nice.

It's handy for kind of short cut calls:
void AddThings(Repo repo, User user) {
    // lots of code producing different items
    // ...
    void Add(Item item) {
        repo.AddThing(user, item);
    }
}



I did this previously with Action<Item> add = (x) => repo.AddThing(user, x); but it had to be defined before the work and is, arguably, kind of messy.
Was This Post Helpful? 0
  • +
  • -

#5 Sheepings   User is offline

  • Senior Programmer
  • member icon

Reputation: 224
  • View blog
  • Posts: 1,260
  • Joined: 05-December 13

Re: Any style recommendations for C# 7.0 local functions?

Posted 11 October 2018 - 06:07 PM

It has some nice bits and bobs in it, and I quite like the pattern matching features. A switch statement can have more than one case clause with the same type, which is cool. In likely situations the compiler groups together all type checks to avoid redundant computations too.
protected void WhichShape(object o)
{
 switch (o)
 {
  case Triangle t:
      labelTriangle.Text = ($"{t.Width} x {t.Height} x {t.Base} triangle");
      break;
  case Rectangle s when (s.Width == s.Height):
      labelSquare.Text = $"{s.Width} x {s.Height} square";
      break;
  case Rectangle r:
      labelRectangle.Text = $"{r.Width} x {r.Height} rectangle";
      break;
  case null:
      throw new ArgumentNullException(nameof(o));
  default:
      labelException.Text = "<unknown shape>";
      break;
 }
}

They are out a while, so why only now are you posting about it Skydiver
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6929
  • View blog
  • Posts: 23,551
  • Joined: 05-May 12

Re: Any style recommendations for C# 7.0 local functions?

Posted 11 October 2018 - 07:08 PM

Yes, C# 7.0 had been out for a while. It is why I was asking if there were any style recommendations specifically for the local functions feature to see what other people have learned from the feature and how to effectively communicate within their teams with the code that they write using the feature.

Just like the var vs. explicit type declarations debate when the feature first was introduced, after a while teams settled on their preferences after sufficient time of trying out using both, and when to break their own rules when needed, I was hoping to see what conventions people have adopted with regards to local functions.
Was This Post Helpful? 0
  • +
  • -

#7 h4nnib4l   User is offline

  • The Noid
  • member icon

Reputation: 1390
  • View blog
  • Posts: 1,979
  • Joined: 24-August 11

Re: Any style recommendations for C# 7.0 local functions?

Posted 24 January 2019 - 04:45 PM

One of the first helpful scenarios I found is pushing tedious initialization chains out of the logic flow. An example is this code whose intent is to kick off an Azure Data Factory pipeline run. It takes almost as many lines of code to initialize the DataFactoryManagementClient object as it does to actually do the work. I think that:

using (var adfClient = GetManagementClient())
{
    // create pipeline run and log results
}

DataFactoryManagementClient GetManagementClient()
{
    var authenticationContext = new AuthenticationContext($"https://login.windows.net/{tenantId}");
    var clientCredential = new ClientCredential(servicePrincipalId, servicePrincipalKey);
    var result = authenticationContext.AcquireTokenAsync("https://management.core.windows.net/", clientCredential).Result;
    var creds = new TokenCredentials(subscriptionId, result.AccessToken);
    return new DataFactoryManagementClient(creds);
}



is easier to read and better communicates the intent of the method than

var authenticationContext = new AuthenticationContext($"https://login.windows.net/{tenantId}");
var clientCredential = new ClientCredential(servicePrincipalId, servicePrincipalKey);
var result = authenticationContext.AcquireTokenAsync("https://management.core.windows.net/", clientCredential).Result;
var creds = new TokenCredentials(subscriptionId, result.AccessToken);

using (var adfClient = new DataFactoryManagementClient(creds))
{
    // create pipeline run and log results
}



Traditionally I'd push that into a separate private method, but I think this is a better solution because it cleans up the logic flow while still keeping the functionality "closer" to the caller, and is less verbose (like Skydiver mentioned) and DRYer because I'm not duplicating the public method's signature in a single-use private method.

Sure, in many cases I should actually be composing that client in a composition root and injecting it, but in a simple Azure Function maintaining a composition root would be pretty excessive.
Was This Post Helpful? 1
  • +
  • -

#8 h4nnib4l   User is offline

  • The Noid
  • member icon

Reputation: 1390
  • View blog
  • Posts: 1,979
  • Joined: 24-August 11

Re: Any style recommendations for C# 7.0 local functions?

Posted 01 June 2019 - 09:12 AM

The sample code in one of your SO answers highlighted what is, in my mind, a very useful application of local functions that hadn't occurred to me but in retrospect is fairly obvious: recursion. I really like that solution over breaking out a separate recursive function to encapsulate logic that is really part of the caller.

Recursion isn't a big part of my programming life, so my experience is probably different than that of others, but I've rarely written a private recursive function that was called by more than one public method in a class. In fact, I think the only time I really do that is in support of public method overloads, which causes a small amount of code duplication in that the recursion management code (for lack of a better term) is duplicated in each overload. With this technique, the overloads are really just managing to the signature of the private method (or the one public overload) that does all of the work, including calling and managing the recursion.

Just like the scenario in my previous reply, I think that encapsulating that functionality locally as opposed to creating a whole new method for exactly one caller is much more elegant and descriptive.

EDIT: grammar

This post has been edited by h4nnib4l: 03 June 2019 - 07:47 AM

Was This Post Helpful? 0
  • +
  • -

#9 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6929
  • View blog
  • Posts: 23,551
  • Joined: 05-May 12

Re: Any style recommendations for C# 7.0 local functions?

Posted 01 June 2019 - 09:36 AM

h4nnib4l was referring to this code from my SO answer:
public static IEnumerable<T[]> Permutations<T>(this IEnumerable<T> source, int k)
{
    if (k < 0)
        throw new ArgumentOutOfRangeException(nameof(k), "May not be negative");

    var items = source.ToArray();
    if (k > items.Length)
        throw new ArgumentOutOfRangeException(nameof(k), "May not be bigger than the number of items in source");

    var buffer = new ArraySegment<T>(items, 0, k);
    return Permute(0);

    IEnumerable<T[]> Permute(int depth)
    {
        if (depth == k)
        {
            yield return buffer.ToArray();
            yield break;
        }

        for (int i = depth; i < items.Length; i++)
        {
            Swap(depth, i);
            foreach (var permutation in Permute(depth + 1))
                yield return permutation;
            Swap(depth, i);
        }
    }

    void Swap(int a, int b )
    {
        if (a != b )
        {
            T t = items[a];
            items[a] = items[b];
            items[b] = t;
        }
    }
}


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1