This month, we had our biggest meetup yet, as we welcomed Jon Skeet himself to .NET Oxford to tell us about some of the upcoming C#8 features. And as you can see from the photo below - he certainly filled the house!...
I've never seen our Meetup.com RSVP-count go up so quickly as it did for this event! It literally filled the max occupancy of 110 attendees within a single day, and we had another 50 members on the waiting list!
We also had a late change of venue, which wasn't actually very far away from our usual venue - ie. literally next door! Our usual venue had had to cancel on us due to building work. This would have obviously been quite stressful if it hadn't been for our amazing sponsors Corriculo Recruitment, saving the day and immediately finding this new venue!
As usual in our intro talks, after doing the usual welcome and house-keeping, I went through some hand-picked news items and then did the prize draws. I normally have details of these at the start of these blog posts - but have decided to instead move them to the end, so that I can focus on the main talk earlier on. If you're interested in details of the news items and prize draws - then scroll down a bit :)
The published slides for the intro talk are available here, and the Reveal.js source code can be found on our Github account.
So whilst I'm sure everyone reading this knows who Jon Skeet is, I should probably start with an intro anyway! Most people will have heard of Jon through his incredible work on Stackoverflow - being the only person to breach the one million reputation mark! Which is insane! He also now works at Google, leading the team building the Google Cloud client libraries for .NET.
I had met Jon before the event started in a local coffee shop, and when chatting with him, one area it was clear he felt very strongly about was diversity in our industry - and very rightly so! I must admit, I realised that whilst I never actively discriminate in any way - I also have never actively tried to improve the situation either. Jon started his talk trying to do just this, and raise everyone's awareness to the situation. He asked everyone to look around the room and notice that it was full of mostly white men, pointing out that this is not representative of the broader community, and that this is our problem to fix. He said that we mustn't try to leave it to those who feel excluded to "just get over it" and improve things. It's not an easy thing to fix, but it's an important thing to fix - and it's to everyone's benefit.
Jon's talk was pretty much 100% code. No fancy PPTs - just plenty of code written by Jon as he explained the different concepts. I quite often see live-coding talks where the audience end up twiddling their thumbs watching the speaker typing. However, this certainly wasn't the case in this talk, and I was extremely impressed in Jon's ability to write code at the same speed as he was explaining what he was writing, whilst still heavily engaging with the audience. Very impressive!
It turns out that he also did this talk remotely the next morning for a user-group in Adelaide, and they recorded it and put it on YouTube. So whilst I try and summarise the talk content below - if you want to see the full talk where Jon goes into a lot more detail, then I'd highly recommend watching that video.
The entire first half of Jon's talk was all about null-reference types. He started explaining what this actually is, and why we need it. I first heard this term, when it was first announced, and was confused by the name ... reference types are already nullable aren't they?! As Jon explains - in C#8, by default - they no longer will be! When this feature is enabled - you'll have to explicitly flag reference types as nullable with the ?
modifier, in the same way as you would do with a value type - eg. int?
, Guid?
, DateTime?
, etc. The reason being that most of our reference types tend to not have a requirement to be nullable anyway, so let's make this the default, so we can make our code safer from the all too common NullReferenceException.
This is obviously a massive change that will change the meaning of pretty much all of your codebase, so once enabled, it will (for the time being) just be compiler warnings. Jon explained how he migrated his NodaTime project, and it was a very iterative process, going through fixing hundreds of warnings one at a time.
Jon showed various different examples of this in use, showing how the IDE can be quite clever when showing squiggly warnings in code if there's a possible null reference exception, and not showing the squiggles if the value can't be null. He also gave a few examples where the compiler might give these squiggly warnings when it shouldn't do, especially when it requires the compiler to know the intent of methods - eg. string.IsNullOrEmpty()
. How this will be handled is still work in progress, and whilst built-in methods like IsNullOrEmpty can be special cased, you still need a way of doing this in your own libraries. Perhaps something like the Jetbrains [CanBeNull]
and [NotNull]
annotations.
After the break, it was time to move onto some other C#8 features. However, when Jon asked the audience who had heard of pattern matching (which is a C#7 feature), enough hands didn't go up to prompt him to give a bit of a refresher before explaining switch expressions (in C#8). He spent quite a bit of time explaining this using some Fibanacii code, which actually flowed quite nicely into explaining Switch expressions.
Rather than explaining here what switch expressions are, here is code pinched from Jon's example showing the Fibanacii sequence using a standard switch statement ...
static int Fib3(int n)
{
switch (n)
{
case 0: return 0;
case 1: return 1;
default: return n >= 0 ? Fib3(n - 1) + Fib3(n - 2) : throw new ArgumentOutOfRangeException();
}
}
... and here is the same example where he tweaked it so use C#7 pattern matching ...
static int Fib3b(int n)
{
switch (n)
{
case _ when n < 0: throw new ArgumentOutOfRangeException();
case 0: return 0;
case 1: return 1;
default: Fib3(n - 1) + Fib3(n - 2);
}
}
... and now, using switch expressions ...
static int Fib4(int n) => n switch
{
_ when n < 0 => throw new ArgumentOutOfRangeException(),
0 => 0,
1 => 1,
_ => Fib4(n - 1) + Fib4(n - 2)
};
That should give you the basic idea. Basically the switch becoming a list of lambdas, rather than case blocks. However, it was a much more interesting journey between those two examples in Jon's talk, with plenty of twists and turns, as he explored various edge cases and gave different examples. Again, I'd recommend watching the recorded version of his talk from the next day.
The next feature that Jon described was the introduction of two new value types - Index
and Range
, and also two new operators - '^
' (hat) and '..
'. An Index is a value type that stores both a typical index (eg. a zero-based int), and also a flag 'FromEnd
'. If FromEnd is true, then the index counts back from the end of whatever it is you're indexing into - otherwise it's from the start like a normal index.
Whilst you can create the Index manually with something like new Index(5, true)
- you can also use the new operators as syntactical sugar, where the hat (^
) operator specifies the FromEnd
flag - eg. var index = ^5
. This is obviously a much shorter and cleaner syntax.
One thing that Jon points out is that whilst when the index from the start is zero-based and intuitive - an index from the end isn't quite as obvious. For example when indexing into a string, 0
refers to the first character. But to refer to the last character, it's ^1
, not ^0
. The way he explained it was to think of the index referring to the cursor inbetween each character. And it'll choose the character to the right of the cursor. So 0
has the cursor to the left of the first character and selects the first character. Whilst, ^0
will have the cursor at the very end of the string, and will be trying to access the character after the end of the string and throw an exception - so should be ^1
instead.
A Range
is just a pair of indexes - ie. a start and an end. And this is where the '..
' operator comes in. An example that Jon gave was taking a range of characters from a string ...
var text = "Hello world";
var stringSlice = text[1..^2];
Console.WriteLine(stringSlice); // Would print "ello wor"
He also pointed out that this is very useful when dealing with the newish Span type, for example ...
ReadOnlySpan<char> span = text.AsSpan();
// Note: should be able to use span[6..] but it doesn't compile, despite the extra extension method :(
ReadOnlySpan<char> spanSlice = span.Slice(6..);
Console.WriteLine(spanSlice.ToString());
Well how long is a piece of string? In fact, I think I remember Jon using that very phrase! He did hint that in a dinner conversation with Mads Torgersen a week earlier, he was suggested that a 2019 release was still on the cards. Jon did stress though that he was confident that the C# team would not release until they were sure it was completely ready.
After Jon had finished, we then moved onto the dev tips. I wasn't actually expecting to have time to do this, as we were overrunning a little bit - however, Jon kindly stopped slightly early, saying that he would rather allow people to get up and do their dev tips. When he said this, I got a bit worried that no-one would get up! Luckily, people did - with some great tips! ...
Ditto Clipboard Manager
The first dev tip was about using the Ditto clipboard manager. Unfortunately, I don't know who it was who gave this tip. If it was you, or you know who it was (see photo above), then please let me know so that I can give credit here. I do highly agree about the usefulness of this tool though, as I use it heavily myself. In fact, if you search for Ditto in my blog post about my Developer Productivity talk, I had a section in the talk about it!
Warnings as Errors
The next dev tip was by Dushyant Priyadarshee - a tip I very strongly agree with! ...
"Almost always enable warnings as error on projects and resolve them (avoid disabling warning)."
Writing better bug reports (me!)
My dev tip was about writing decent bug reports. I've actually recently written a blog post about this, so rather than repeating my tip here - see my post "It doesn't work!". Basically, try and get it so that the other person does not need to come back to you to ask questions. This back and forth is such a huge waste of time in our industry. Take screenshots, even record an animated gif using ScreenToGif if text and screenshots don't say enough.
Comments: Why, not What
This tip was by Marc Evans, and was about commenting code - saying you should focus on the why, not the what. There were plenty of nods from the audience for this one, and something I definitely agree with!
Jon Skeet
We always ask our speaker if they'd like to do one too, and this was Jon's tip ...
"Read up on intersectional feminism. It will make you a better developer. I'm completely serious about this. The better we can understand (and communicate with) our users, team-mates and other colleagues, the better we will be as developers. That requires empathy, which in turn requires understanding that our experiences are not those of others. My experience of walking about to the Westgate car park may well be very different from that of an 18 year old woman. Recognizing that, and listening to those with experiences different to our own, is crucial if we want to solve problems for everyone rather than just 'people like us'."
Since our last meetup, Microsoft had had their Ignite Conference, which brought a ton of new announcements, especially in the Azure space. We obviously couldn't begin to list them all, but here are the ones I picked out...
AKS Virtual Nodes (private preview)
The first news item was about Virtual Nodes for Azure Kubernetes Services (AKS) going into private preview. This allows AKS to take advantage of Azure Container Instances (ACI) to move a bit closer towards making Kubernetes "serverless".
Azure Functions 2.0 (GA)
The next news item was about the next version of Azure Functions going into GA. This brings a whole bunch of changes - including support for the .NET 2.1 runtime - meaning it can run locally cross platform on Windows, Linux, or Mac - and also in other places, eg. Kubernetes and IoT Edge!
Azure SignalR Service (GA)
SignalR has been around for a long time, but to properly scale it out in the cloud requires quite a bit of work managing the backplane, etc. This new Azure service allows you to just create a service (in typical cloud click and go fashion) and let the service do all the work for you. It also makes it easier to scale SignalR separately to your web application.
If you're interested in this, then I'd strongly recommend listening to this .NET Rocks episode which goes into the new SignalR service in detail.
Microsoft Learn
At Ignite, Microsoft announced a new learning platform - Microsoft Learn. Rather than being plain old documentation where sometimes it's hard to know where to start - this instead takes you through learning paths in various topics. It seems very focused on Azure material at the moment, but this is fine by me! Has a very Katacoda-like feel with step by step instructions on the left, and an interactive shell on the right - allowing you to learn by doing.
https://docs.microsoft.com/learn
SQL Server 2019 (public preview)
Another announcement was the preview of SQL Server 2019. I didn't go into details for this one, as I hadn't had chance to read up on them! But as it's obviously a big release - I thought it was at least worth mentioning!
Stackoverflow is 10 years old!
This news item is obviously very on-topic, as most of us have probably heard of Jon through his fantastic work on Stackoverflow! The title says it all - Stackoverflow is now a decade old! Which is a lifetime in our industry! Happy Birthday Stackoverflow - you've saved us all on a daily basis!
(Link to Stackoverflow blog post)
Once again, our amazing primary sponsor, Corriculo Recruitment, did a fantastic job at the event - welcoming people in, manning the doors checking RSVPs, supplying and serving drinks and refreshments, and much more. And this is on top of all the other stuff they do for us - not only helping us out financially, paying for the venue hire and supplying the drinks and refreshments - but also with ideas and suggestions, marketing and promotion, and much more. A core part of the .NET Oxford team, and I really can't thank them enough for all they do.
In fact, this very event should have been at our usual venue, but after we had booked and filled the Meetup.com RSVP list, the venue had to cancel due to a mixup with their refurbishment. As you can imagine, this would have been incredibly stressful, if it wasn't for Corriculo immediately finding the alternative venue and sorting it all out for us.
In the intro talk - I asked everyone to give Corriculo a massive round of a applause for all they do, including sorting this venue problem out - and you could tell by the sheer volume of the applause how genuine everyone felt about their appreciation to all Corriculo do for us.
Our secondary sponsor is my own company, Everstack. Providing a lot of my own time for organising and managing .NET Oxford. Everstack provides software development and consultation services - specialising in .NET and the Cloud.
After the news, we then moved onto the prize draws, using my usual WPF Prize Draw app. A massive congratulation to the winners, and a massive thank you to our awesome prize draw sponsors ...
Congratulations to Tom Lane for winning a year-long Jetbrains product licence!
Congratulations to Jonathan Madelaine for winning a Manning ebook! The winner has the choice of any of the awesome Manning ebooks from their website, and Johnathon chose React in Action.
Remember that we have our special Manning coupon code (ug367) which gives all of our members a 36% discount on any of their e-books! They've also asked me to share a link to some of their new courses for their LiveVideo system.
Congratulations to Oksana Meme for winning the Oz-Code licence!
For those that don't know, Oz-Code is a Visual Studio extension that puts your debugger on steroids. Take a look at their website for videos of their features. If you haven't checked it out, then definitely download the trial and have a play. All our member get a free 3 month trial licence (see below) or 50% off a full licence! To claim, you can visit this link to pick up your licence!
As usual, we headed to the pub after the event finished. Beforehand, I'd popped into one of our regulars, the Royal Blenheim, and reserved the back area, which they call The Snug. Always great having the chance for a proper catch-up after the event. Lots of great nerdy conversations and geek-outs!
Below are our upcoming meetups. We'll be planning more meetups for next year shortly, and if you subscribe to the meetup group, you'll get email notifications as they are announced.
November: Performance in the JavaScript Era - Benjamin Howarth:
November will be with Benjamin Howarth, talking about various different aspects of performance in an era where much more functionality has been pushed to the frontend. This isn't just a JavaScript talk though - it covers a lot of aspects that are important to us .NET developers too!
December: More Lightning Talks!
In December, we have another lightning talk event. All slots are currently taken and here are the talks (in no particular order) ...
January 2019: NGINX for .NET Developers - Ian Cooper
In January, Ian Cooper will be back (after his very popular 12 Factor App talk) earlier this year. This time, his talk will be all about NGINX for .NET developers!
Please retweet if you enjoyed this post ...
Blogged: Jon Skeet at .NET Oxford - C#8, The Story So Far https://t.co/4X8rgqPvoU @jonskeet @dotnetoxford #dotnet pic.twitter.com/AkJUMJzXz6
— Dan Clarke (@dracan) October 17, 2018