BT

New Early adopter or innovator? InfoQ has been working on some new features for you. Learn more

An Early Look at C# 7.1: Part 1

| by Jonathan Allen Follow 131 Followers on Jun 05, 2017. Estimated reading time: 3 minutes |

For the first time since 2003, Microsoft is considering a point release for C#. Currently marked as C# 7.1, the next version of the language is expected to include Async Main, Default Expressions, Infer Tuple Names, and Pattern-matching with Generics.

Async Main

Often frustrating for developers who are experimenting with asynchronous code, is the fact that console applications currently don’t support an asynchronous entry point. The workaround is a couple lines of boilerplate code, but the pattern isn’t obvious because it relies on methods that are not normally used.

public static void Main()
{
    MainAsync().GetAwaiter().GetResult();
}

private static async Task MainAsync()
{
    ... // Main body here
}

To address this, the Async Main proposal simply adds four new signatures to the list of possible entry points.

static Task Main()
static Task<int> Main()
static Task Main(string[])
static Task<int> Main(string[])

If one of these entry point functions is present then the compiler will generate the necessary boilerplate, unless you also have a non-async Main function. This last restriction is needed for backwards compatibility.

They had considered allowing “async void Main()”, but that made the compiler more complicated and in general Microsoft wants to discourage the use of “async void” outside of event handlers.

Default (i.e. Nothing)

One of the subtle differences between C# and VB is that VB doesn’t have a keyword that means “null”. There is the keyword “Nothing”, but that is described in the language specification as,

Nothing is a special literal; it does not have a type and is convertible to all types in the type system, including type parameters. When converted to a particular type, it is the equivalent of the default value of that type.

Currently C# uses the pattern “default(T)” to get the same effect, but that can become a bit tedious, especially with long class names. With C# 7.1, we’ll have a “default literal” described as,

An expression with this classification can be implicitly converted to any type, by a default-or-null literal conversion.

The inference of the type for the default literal works the same as that for the null literal, except that any type is allowed (not just reference types).

The default literal can be used in most places where you could have used null. This is seen as a drawback in the proposal, presumably because it is generally frowned upon to have two very similar ways of doing the same thing. The design meeting notes ask,

Are we setting up for style wars?

The following example uses of the default literal:

ImmutableArray<SomeType> x = default;
return default;
void Method(ImmutableArray<SomeType> arrayOpt = default)
var x = new[] { default, ImmutableArray.Create(y) };
const int x = default;
if (x == default)
if (x is default)
y = default as RefType //compiler warning: always null
int i = default

The following are illegal uses of the default literal:

const int? y = default;
if (default == default)
if (default is T)
var i = default
throw default

The last one is a weird artifact of the C# design. From the design meeting notes,

You are allowed to throw null in C#. It leads to a runtime error, which ironically causes a NullReferenceException to be thrown. So it is a sneaky/ugly idiom for throwing a NullReferenceException.

There's no good reason to allow this for default. We don't think the user has any intuition that that should work, or about what it does.

Instead of introducing the default literal, they considered simply extend “null” to have the same effect. VB can do this because “nothing” and “null” are different words. VB still has the concept of a null even without the keyword; so you see things like a “NothingReferenceException”.

In C#, you would be constantly asking, “Do you mean null as in actually null or null as in the default value which may or may not be null?”. The conclusion was that it was too confusing.

In Part 2 we’ll look at tuples and pattern matching.

Rate this Article

Adoption Stage
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread
Community comments

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Discuss

Login to InfoQ to interact with what matters most to you.


Recover your password...

Follow

Follow your favorite topics and editors

Quick overview of most important highlights in the industry and on the site.

Like

More signal, less noise

Build your own feed by choosing topics you want to read about and editors you want to hear from.

Notifications

Stay up-to-date

Set up your notifications and don't miss out on content that matters to you

BT