That Conference 2018 – What’s New in C#7

That Conference 2018, Kalahari Resort, Lake Delton, WI
What’s New in C#7 – Jason Bock

Day 2, 7 Aug 2018  4:00 PM

Disclaimer: This post contains my own thoughts and notes based on attending That Conference 2018 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of the speakers.

Executive Summary

  • Brief review of history of C# versions
  • Lots of good new stuff in C# 7
  • Importance of C# and .NET now being open source

Language Evolution

  • C# – 2002, .NET 1.0
  • v1 – classes, evenst, properties
  • v2 – generics, partial types, anonymous methods, nullable types
  • v3 – LINQ, implicit types, extension methods, lambda expressions
  • v4 – dynamic binding, embedded interop types, named arguments
  • v5 – async/await, caller info attributes
  • v6 – Roslyn, exception filters, await in catch, auto prop initializer, default values for getters, expression-bodied members, string interpolation, null propagator, nameof
  • v7 – out variables, tuples, local functions, binary literals, ref returns/locals, throw expressions
  • v7.1
  • v7.2
  • v7.3

.NET Foundation

  • Foster open source development
  • Everything in .NET is now open source, on github
  • Contributors from both inside/outside MIcrosoft

.csproj file

  • Can target LangVersion, or latest

Binary digits, digit separators

  • Underscore in integer constant is separator–doesn’t do anything
  • Can do one or more underscores anywhere you like
  • 0b – binary literals

Local functions

  • Declare functions within functions
  • Compiled as private methods, so performance is the same as private methods

Out var

  • Replaces big try/catch block
  • Or TryParse
  • 3rd way in C# 7 – declare out var directly in method call

Ref Returns and Locals

  • Copy semantics for structs
  • Traditional list, indexer returns element, copied if element is value typed
  • Indexer can use ref keyword to pass element back by reference
    • For value typed objects, you get a reference to the value-typed object
  • Far faster (if elements are large)
  • Where you assign the element, you also use ref keyword

Pattern Matching

  • Using switch statement
  • Pass in parameter of parent type, then case on child type
  • Can also add when clause to trigger on stuff specific to that subtype
  • default case can be anywhere
  • case null

Tuples

  • Not Item1, Item2 syntax from v5
  • Lets say that you want to pass two values back out of a function
  • public (int, int) ReturnTwoInts() { … }
  • Maps to ValueTuple, which has Item1, Item2, etc.
  • Can do named values
  • public (int x, int y) ReturnTwoInts
    • Can now ref result.x, result.y
  • Calling it
    • (var x, var y) = ReturnTwoInts()
  • Can use _ to indicate you don’t care
  • Deconstruct method – pull data out as tuple (?)
  • Can use tuples as concrete types in generics
  • Assign multiple properties in a single line of code with a tuple

ValueTask<T>

  • Task is a reference type, but you might want a value-typed task for performance
  • ValueTask<T> is just a struct that does everything that a Task does
  • You’d use this only if you really need the added performance

Expression bodied members

  • Define wherever you like, not just read-only properties

[C# 7.1]

async main method

Default literals

  • Instead of default(int), you can infer the type of the default
  • So just use default keyword, type is inferred

[C# 7.2]

readonly struct

Spans

  • Look at chunk of memory
  • “Safe” way to read/write direct memory
  • e.g. “11,22” .AsSpan()
  • .Slice instead of Substring
  • No allocations
  • More performant

Constraint Generic

  • To enum type, to delegate type
  • where T : Enum

Compare Tuples

  • Equality semantics is correct

Backing field not serialized

  • On auto property, do [field: NonSerialized]

Future Directions

  • Ranges – foreach, in 5..10
  • Default Interface Methods – default implementation for a method on an interface
    • Looks odd
  • Nullable reference types
    • Have to opt-in, to avoid breaks
    • Once opt-in, MyClass mc would be non-nullable
    • Have to do MyClass? to get nullable
    • n!.Length – don’t worry about null-check
  • async streams – async enumerator
  • Generic attributes – e.g. [MyAttribute<int>]
  • Records and with expressions
  • Shapes and extensions
    • Mads T
    • Extensions everywhere – e.g. properties

Questions

Q: Isn’t this scary / dangerous? What is the main use case?

A: Multiple return values, e.g. int.Parse that is more elegant because it returns multiple things. Helps to avoid defining little objects designed just to pass data around between methods

Leave a comment