Friday Links 0.0.26 - C#-7: Literals, Async, and Throw Expressions
This is based on an email I send my .NET team at work
Happy Friday,
It appears to have been almost 2 months since I last sent one of these. My apologies for the laziness. I’m sure you wait every Friday with bated breath for a happy little notification in your email client.
Lets talk briefly about a few more new features in C#-7, which you can use today in VS2017.
New Literal Features
A literal is a funny language designer term for a value specified directly in
source code, like 5
or "somestring"
.
In case you were ever using large integers, you should be happy to know you can now place underscores anywhere in the number and have it ignored by the compiler.
int i = 42_234;
int hex = 0xBAD_F00D;
This is a small feature, and I guess its nice.
I actually got bitten by a bug just yesterday where I could have been saved with
this. I couldn’t figure out why my math was always turning out to be off by a
factor of 10. It took me a minute to realize I had const int MAX = 10000
instead of const int MAX = 1000
.
Digit separators might have made it more obvious: const int MAX = 10_000
is a
little more distinguishable from const int MAX = 1_000
.
Here’s the feature proposal for your entertainment: https://github.com/dotnet/roslyn/issues/216
Oh, and they also added binary literals. This is for when you need to specify bit patterns directly, and is a little bit nicer than hex codes.
byte b8 = 0b1001101;
short b16 = 0b10110011110111010;
Combine it with the digit separator feature to split out the different bytes.
As primarily web programmers, we probably won’t run into much need for binary
literals, but they’re nice to have for infuriating the rest of your team.
Replace all the numbers in your application with binary literals: they might
enjoy the challenge of translating them. And if they’re one of the 10
types of
people who can’t read binary, they don’t deserve to be on a team of such high
caliber developers as you.
Here’s the feature proposal: https://github.com/dotnet/roslyn/issues/215
Generalized async return types
This is not a feature you would use directly, but certain library authors would be happy to have it.
Normally async methods have to return Task
or Task<T>
. This feature lets
those methods return any type of object that quacks like Task
or Task<T>
.
I’m not sure of the specifics, but there are probably a couple of methods you
have to implement like GetAwaiter()
and Result
, etc.
The main purpose was to allow the creation of ValueTask
and ValueTask<T>
.
Unlike Task
and Task<T>
, this async return type is a struct
not a class
.
Thus there is no dynamic memory allocation or garbage collection. In some
high performance scenarios, this can reduce GC pauses.
To use ValueTask
you’ll need to load this nuget package:
System.Threading.Tasks.Extensions.
This change probably won’t effect your day to day. If a library starts using
ValueTask
you probably wouldn’t even notice, since it works the same way as
Task
.
Just be aware.
Here’s the implementation of ValueTask
: https://github.com/dotnet/corefx/blob/master/src/System.Threading.Tasks.Extensions/src/System/Threading/Tasks/ValueTask.cs
Here’s one of the proposals for the feature: https://github.com/dotnet/roslyn/issues/7169
Throw Expressions
In previous versions of C# the throw
keyword was always a statement. This meant
it had to be used on a line of its own which made certain patterns annoying.
Now, it can be an expression in some contexts.
For example, in assignment:
class Foo
{
private IService _service;
Foo(IService service)
{
_service = service ?? throw new ArgumentNullException(nameof(service));
}
}
Previously you would need an if
statement to check the parameter for null
. I
like this feature, it will make parameter validations a lot cleaner.
Here’s the initial proposal: https://github.com/dotnet/roslyn/issues/5143
Next time we talk about Tuples, a much bigger change to the language. Stay tuned.