Friday Links 0.0.24 - C#-7: Out Variables and Local Functions

This is based on an email I send my .NET team at work

Happy Friday,

Over the next few weeks I’m going to be taking a look at some of the new features in C#-7, that just became available with the recent release of Visual Studio 2017.

Out Variables

I’m sure you’ve used a lot of the .NET’s Try* functions, like int.TryParse. These functions return a bool indicating if the method succeeded, and then returning the real result as an out parameter.

They’re kind of clunky to use because you have to declare the variable before hand:

1
2
3
4
5
int page;
if (int.TryParse(Request.QueryString["page"], out page))
{
// do something with the page
}

With this new feature, you can move the declaration to inside of the method call:

1
2
3
4
if (int.TryParse(Request.QueryString["page"], out int page))
{
// do something with the page
}

You can also now use var instead of the type delcaration

You can also ignore the out variable. For example, if I cared that a string was parseable to an int but didn’t care what the actual value was.

1
2
3
4
public static bool IsIntString(string s)
{
return int.TryParse(s, out _);
}

Notice there is no type declaration. The variable has to be _ or else its a compile error.

What’s also funny is that Resharper (2016.3.2) thinks the above is an error, though it compiles just fine.

The new feature is syntactic sugar for the old version, and doesn’t change the semantics of the code.

Here was the initial proposal for the feature: https://github.com/dotnet/roslyn/issues/6183

What’s interesting is that initially they wanted to change the scope of the out variable: it would only be accessible inside of the if block. It looks like that design was dropped somewhere along the way.

I really like this feature and it will help clean up a lot of clunky Try* code.

Local Functions

You can now declare functions inside of other functions. This is meant for utility functions that are only really helpful in one place. You’ll never need to call it from elsewhere.

1
2
3
4
5
6
7
8
9
public static int LocalFunctionTest()
{
return GetInteger();
int GetInteger()
{
return 10;
}
}

You could have used local lambdas like Action<T> in earlier versions of C#, but lambdas don’t let you use out and ref variables.

Local functions can also helpfully reference local variables through closures:

1
2
3
4
5
6
7
8
9
10
11
12
public static void LocalFunctionTestWithClosure()
{
string s = "hi";
Console.WriteLine(ConcatWorld());
string ConcatWorld()
{
// s comes from enclosing scope
return s + " world";
}
}

I think there are a few scenarios where this feature could be pretty useful, but I’d be wary of over use. You probably shouldn’t find yourself using more than a couple local functions in a given method. I think I’m still inclined to use a regular utility function unless I had good reason to turn it into a local.

I need a little more experience with this feature to determine how I like it.

Here’s the original proposal: https://github.com/dotnet/roslyn/issues/259