C C # # 7, 7, 8, 8, and beyon ond: lang languag uage e fe features from design to to release to to IDE su support ort Kevin Pilch kevinpi@microsoft.com @Pilchie
ck Overflow - most popular technologies Stack http://stackoverflow.com/insights/survey/2017#most-popular-technologies
rflow - most loved technologies Stack Overf St http://stackoverflow.com/insights/survey/2017#most-loved-dreaded-and-wanted
Changing the tune - Why you can use C# Ch Run on Windows Run everywhere Black box compilers Open compiler APIs Edit in Visual Studio Use your favorite editor Proprietary Open source
C# C# everyw ywhere - Xamarin
everywhere - Unity C# C# ev
everywhere - .NET Core C# C# ev
Roslyn – the C# language engine Ro The here sho houl uld ne need d to be be onl nly on one co code base in n the the world d for unde understandi nding ng C#
OmniSharp – edit C# everywhere Om
C# Evolution – A balancing act C# Stay simple Aggressively improve Improve existing development Attractive to new users Stay true to the spirit of C# Embrace new paradigms
C# - evolution C# C# 7 Work with C# 6 data Eliminate C# 5 ceremony Async C# 4 Dynamic, C# 3 Concurrency Queries, C# 2 Lambdas Generics C# 1 Hello World
C# 6 - recap C# Expression bodied members String Interpolation Conditional access operator nameof Using static Exception Filters Interactive window
Demo: C# 7.0
C# C# 7. 7.0 0 – what’s new static void Main(string[] args) { object[] numbers = { 0b1, 0b10, new object[] { 0b100, 0b1000 }, // binary literals 0b1_0000, 0b10_0000 }; // digit separators var (sum, count) = Tally(numbers); // deconstruction WriteLine($"Sum: {sum}, Count: {count}"); } static (int sum, int count) Tally(object[] values) // tuple types { var r = (s: 0, c: 0); // tuple literals void Add(int s, int c) { r.s += s, r.c += c; } // local functions return r; }
7.0 – what’s new C# C# 7.0 static (int sum, int count) Tally(object[] values) // tuple types { var r = (s: 0, c: 0); // tuple literals void Add(int s, int c) { r.s += s, r.c += c; } // local functions foreach (var v in values) { switch (v) // switch on any value { case int i: // type patterns Add(i, 1); break; case object[] a when a.Length > 0: // case conditions var t = Tally(a); Add(t.sum, t.count); break; } } return r; }
C# C# 7.0 7.0 – what’s new Binary literals Digit separators Tuples Patterns Local functions “Tasklike” async methods Out “var” “ref” locals and returns Throw expressions More expression bodied members
C# C# 7.1 7.1 – introducing point releases “default” expressions Async main Infer tuple names Reference assemblies
C# C# 7.2, 7.2, 8.0, 8.0, … … – long term thinking “ref readonly” “blittable” Interior pointer (needed for Span<T>) Nullable Reference Types Default Interface methods
Nullable and non-nullable reference types string? n; // Nullable reference type string s; // Non-nullable reference type n = null; // Sure; it's nullable s = null; // Warning! Shouldn’t be null! s = n; // Warning! Really! WriteLine(s.Length); // Sure; it’s not null WriteLine(n.Length); // Warning! Could be null! if (n != null) { WriteLine(n.Length); } // Sure; you checked WriteLine(n!.Length); // Ok, if you insist!
Default implementations public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset() => throw new InvalidOperationException("Reset not supported"); } public interface IEnumerator<out T> : IDisposable, IEnumerator { new T Current { get; } object IEnumerator.Current => Current; }
C# C# 8.0, 8.0, … … – long term thinking Extension Everything Async Streams and Disposables More patterns: recursive, tuples, expressions, etc Records Discriminated Unions Creating Immutable objects
Extension everything extension Enrollee extends Person { // static field static Dictionary<Person, Professor> enrollees = new(); // instance method public void Enroll(Professor supervisor) { enrollees[this] = supervisor; } // instance property public Professor Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null; // static property public static ICollection<Person> Students => enrollees.Keys; // instance constructor public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); } }
Async streams and disposables IAsyncEnumerable<Person> people = database.GetPeopleAsync(); foreach await (var person in people) { // use person } using await (IAsyncDisposable resource = await store.GetRecordAsync(…)) { // use resource }
Recursive patterns if (o is Point(_, var y)) { WriteLine($"Y: {y}"); } if (o is Point { Y: var y }) { WriteLine($"Y: {y}"); }
Pattern matching expressions var s = match (o) { int i => $"Number {i}", case Point(int x, int y) => $"({x},{y})", string s when s.Length > 0 => s, null => "<null>", _ => "<other>" };
Tuples in patterns state = match (state, request) { (Closed, Open) => Opened, (Closed, Lock) => Locked, (Opened, Close) => Closed, (Locked, Unlock) => Closed, _ => throw new InvalidOperationException(…) }
Records and discriminated unions record Person(string First, string Last); class Person : IEquatable<Person> { public string First { get; } public string Last { get; } public Person(string First, string Last) { this.First = First; this.Last = Last; } public void Deconstruct(out string first, out string last){ first = First; last = Last; } public bool Equals(Person other) => other != null && First == other.First && Last == other.Last; public override bool Equals(object obj) => obj is Person other ? Equals(other) : false; public override int GetHashCode() => GreatHashFunction(First, Last); … }
Creating immutable objects var p1 = new Point { X = 3, Y = 7 }; var p2 = p1 with { X = -p1.X };
Questions and resources? Language https://github.com/dotnet/csharplang Implementation https://github.com/dotnet/roslyn Reference http://source.roslyn.io Contact https://twitter.com/roslyn Content https://github.com/Pilchie/QConSP/ Me kevinpi@microsoft.com @Pilchie – Twitter/GitHub
Recommend
More recommend