C C # # 7, 7, 8, 8, and beyon
- nd:
lang languag uage e fe features from design to to release to to IDE su support
- rt
Kevin Pilch kevinpi@microsoft.com @Pilchie
C C # # 7, 7, 8, 8, and beyon ond: lang languag uage e fe - - PowerPoint PPT Presentation
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
Kevin Pilch kevinpi@microsoft.com @Pilchie
http://stackoverflow.com/insights/survey/2017#most-popular-technologies
http://stackoverflow.com/insights/survey/2017#most-loved-dreaded-and-wanted
Stay simple Improve existing development Stay true to the spirit of C# Aggressively improve Attractive to new users Embrace new paradigms
C# 1 Hello World C# 2 Generics C# 3 Queries, Lambdas C# 4 Dynamic, Concurrency C# 5 Async C# 6 Eliminate ceremony C# 7 Work with data
Expression bodied members String Interpolation Conditional access operator nameof Using static Exception Filters Interactive window
static void Main(string[] args) {
{ 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; }
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; }
Binary literals Digit separators Tuples Patterns Local functions “Tasklike” async methods Out “var” “ref” locals and returns Throw expressions More expression bodied members
“default” expressions Async main Infer tuple names Reference assemblies
“ref readonly” “blittable” Interior pointer (needed for Span<T>) Nullable Reference Types Default Interface methods
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!
public interface IEnumerator {
bool MoveNext(); void Reset() => throw new InvalidOperationException("Reset not supported"); } public interface IEnumerator<out T> : IDisposable, IEnumerator { new T Current { get; }
}
Extension Everything Async Streams and Disposables More patterns: recursive, tuples, expressions, etc Records Discriminated Unions Creating Immutable objects
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); } }
IAsyncEnumerable<Person> people = database.GetPeopleAsync(); foreach await (var person in people) { // use person } using await (IAsyncDisposable resource = await store.GetRecordAsync(…)) { // use resource }
if (o is Point(_, var y)) { WriteLine($"Y: {y}"); } if (o is Point { Y: var y }) { WriteLine($"Y: {y}"); }
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>" };
state = match (state, request) { (Closed, Open) => Opened, (Closed, Lock) => Locked, (Opened, Close) => Closed, (Locked, Unlock) => Closed, _ => throw new InvalidOperationException(…) }
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); … }
record Person(string First, string Last);
var p1 = new Point { X = 3, Y = 7 }; var p2 = p1 with { X = -p1.X };
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