Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

C# 7.x What's new and what's coming with C# 8

42 views

Published on

C# is extended in a fast pace – with new features allow to reduce the code you need to write, offer more safety, and gives better performance – and you still write safe code. In this session you are introduced to the new C# 7.0-7.3 features including tuples and pattern matching, and learn about the features planned with C# 8.0 such as nullable reference types, extensions for pattern matching, and the new switch expression.

Published in: Software
  • Be the first to comment

  • Be the first to like this

C# 7.x What's new and what's coming with C# 8

  1. 1. C# 7.x What’s new and What’s coming with C# 8 #THRIVEITCONF
  2. 2. C# STRATEGY
  3. 3. Continuous enhancements Fulfill changing needs
  4. 4. Agenda C# Strategy C# Today C# Future
  5. 5. Christian Nagel • Independent Consultant • Training • Coaching • Coding • Writing csharp.christiannagel.com www.cninnovation.com @christiannagel Microsoft MVP
  6. 6. Fast innovations Spirit of C#
  7. 7. Goals with C# 7.1, 7.2, 7.3 • Reduce garbage collection • No copy • "Safe" Code Efficient Code • Additional possibilities More Options • "Say it shorter" Less Code
  8. 8. C# 8 Magic
  9. 9. C# 7.X TODAY
  10. 10. C# 7.0 Tuples & Deconstruction Pattern Matching Expressions everywhere Reference Semantics
  11. 11. Tuples • Combine different types • Strong Names • Value Types var t1 = (n: 42, s: "magic"); int i1 = t1.n; string s1 = t1.s;
  12. 12. Deconstruction • Create parts from objects or tuples • Implement method Deconstruct var p1 = new Person("Tom", "Turbo"); (string firstName, string lastName) = p1;
  13. 13. Pattern Matching (C# 7.0) • is Operator and switch statement extended • Const Pattern • Type Pattern • Var Pattern public void IsSample(object o) { if (o is 42) { } if (o is Person p) { } if (o is var v1) { } } public void PatternMatchingWithSwitchStatement(object o) { switch (o) { case 42: break; case Person p when p.FirstName == "Katharina": break; case Person p: break; case var v: break; } }
  14. 14. Reference Semantics • return values by reference • Span<T> Type public ref int ReturnValueByReference(int[] data, int index) { ref int x = ref data[index]; // local ref return ref x; // ref return }
  15. 15. C# 7.1 • Async main • Generics pattern match • Infer tuple names • Target typed default static async Task Main() { await FooAsync(); } public void Send<T>(T packet) where T : Packet { if (packet is KeepalivePacket keepalive) { } var t1 = (racer.FirstName, racer.Wins); int wins = t1.Wins; ImmutableArray<int> arr = default(ImmutableArray<int>);ImmutableArray<int> arr = default;
  16. 16. C# 7.2 • Leading Separator • Non-trailing named arguments • private protected • Conditional Ref • readonly ref • Span Safety ushort b1 = 0b_1010_1111_0101_0000; if (Enum.TryParse(day, ignoreCase: true, out DayOfWeek weekday)) { reservation.Weekday = weekday; }
  17. 17. C# 7.3 • Auto Property Field Attributes • Generic constraints • unmanaged, Enum, Delegate • Expression Variables in Initializers • Pattern-based fixed statement • Ref local reassignment • Stackalloc array initializers [Serializable] public class Foo { [field: NonSerialized] public string MySecret { get; set; } } void Hash<T>(T value) where T : unmanaged { } var d1 = stackalloc int[3] { 1, 2, 3 }; var d2 = stackalloc int[] { 1, 2, 3 }; var d3 = stackalloc[] { 1, 2, 3 };
  18. 18. C# 7 Point Releases • Safe, efficient code • More options • Reduce code writing
  19. 19. C# 8
  20. 20. State Proposal Discussed/Decision in LDM Prototype Implementation in Progress Implemented
  21. 21. State: Implemented • Default literal deconstruction (not yet in VS 2019) • Alternative interpolated verbatim strings (VS 2019 Preview 1 – [16.0pv1]) (int i, string j) = (default, default); // C# 7 (int i, string j) = default; // C# 8 var foo = $@"c:foo{someFile}" // C# 7 var foo = @$"c:foo{someFile}" // C# 8
  22. 22. State: In Progress • Generic attributes • Relax ordering ref and partial modifiers • Null coalescing assignment (16.0pv1) • Async streams (16.0pv1*) • Ranges (16.0pv1) public class ValidationAttribute<T> : Attribute { } if (variable == null) // C# 7 { variable = expression; } Variable ??= expression; // C# 8 public ref partial class { } // C# 7 public partial ref class { } // C# 8
  23. 23. State: Prototype • Caller expression attribute • Target-typed new • Pattern-based using • Default interface methods • Nullable reference type (16.0pv1) • Recursive patterns // C# 7 private Dictionary<string, List<int>> field = new Dictionary<string, List<int>>() { { "item1", new int[] { 1, 2, 3 } } }; // C# 8 private Dictionary<string, List<int>> field = new() { { "item1", new() { 1, 2, 3 } } }; public static class Debug { public static void Assert(bool condition, [CallerArgumentExpression("condition")] string message = null); } Debug.Assert(array.Length == 1); Debug.Assert(array.Length == 1, "array.Length == 1");
  24. 24. Default Interface Methods Chang interfaces without breaking changes Traits – Reuse methods in independent types Based on Java's default methods
  25. 25. Default Interface Methods • Changing the interface without breaking changes public interface ILogger { void Log(string message); } public interface ILogger { void Log(string message); void Log(Exception ex) => Log(ex.Message); } public class MyLogger : ILogger { public void Log(string message) => Console.WriteLine(message); }
  26. 26. • private • protected • internal • public • virtual • abstract • override • sealed • static • extern Default Interface Methods Allowed Modifiers
  27. 27. Default Interface Methods Multiple Inheritance with interfaces? interface I0 { void M() => Console.WriteLine("I0"); } interface I2 : I0 { override void M() => Console.WriteLine("I2"); } interface I1 : I0 { override void M() => Console.WriteLine("I1"); } interface I3 : I1, I2 { void I0.M() => I2.base.M(); }
  28. 28. Default Interface Methods Most specific override Rule interface I0 { void M() => Console.WriteLine("I0"); } interface I2 : I0 { override void M() => Console.WriteLine("I2"); } interface I1 : I0 { override void M() => Console.WriteLine("I1"); } // error – no most specific override rule for IA.M interface I3 : I1, I2 { } // error – no most specific override rule for IA.M abstract class C : I1, I2 { } abstract class C : I1, I2 { public abstract void M(); }
  29. 29. Default Interface Methods Re-Abstract interface I0 { void M(); } interface I2 : I0 { override void M(); } interface I1 : I0 { override void M() => Console.WriteLine("I1"); }
  30. 30. Async Streams • async/await returns a result • Async Streams  stream of results • Asynchronous sources controlled by the consumer • Alternative to System.Reactive
  31. 31. Async Streams • IAsyncDisposable • IAsyncEnumerable • IAsyncEnumerator public interface IAsyncDisposable { ValueTask DisposeAsync(); } public interface IAsyncEnumerable<out T> { IAsyncEnumerator<T> GetAsyncEnumerator(); } public interface IAsyncEnumerator<out T> : IAsyncDiposable { ValueTask<bool> MoveNextAsync(); T Current { get; } }
  32. 32. Using Async Streams • await foreach IAsyncEnumerator<T> enumerator = enumerable.GetAsyncEnumerator(); try { while (await enumerator.MoveNextAsync()) { Use(enumerator.Current); } } finally { await enumerator.DisposeAsync(); } await foreach (var i in enumerable) { Use(i); }
  33. 33. Async with yield • return IAsyncEnumerable static async IAsyncEnumerable<int> MyIterator() { try { for (int i = 0; i < 100; i++) { await Task.Delay(1000); yield return i; } } finally { await Task.Delay(200); Console.WriteLine("finally"); } }
  34. 34. Async Streams Open Questions • LINQ • ~600 new methods would be necessary • Interactive Extensions (Ix) implements most •  Support Community to extend Ix • Integration with IObservable<T> • Integration using libraries
  35. 35. Patterns Extended • Always match Discard Pattern • Match property values Property Pattern • Match inner properties Recursive Pattern • Modern switch syntax switch Expression
  36. 36. Pattern Matching Now static string M1(Shape shape) { switch (shape) { case Shape s when s.Size.height > 100: return $"large shape with size {s.Size} at position {s.Position}"; case Ellipse e: return $"Ellipse with size {e.Size} at position {e.Position}"; case Rectangle r: return $"Rectangle with size {r.Size} at position {r.Position}"; default: return "another shape"; } }
  37. 37. switch Expression static string M2(Shape shape) => shape switch { Shape s when s.Size.height > 100 => $"large shape with size {s.Size} at position {s.Position}", Ellipse e => $"Ellipse with size {e.Size} at position {e.Position}", Rectangle r => $"Rectangle with size {r.Size} at position {r.Position}", _ => "another shape" } };
  38. 38. Recursive, Property, and Discard Patterns static string M3(Shape shape) => shape switch { CombinedShape (var shape1, var (pos, _)) => $"combined shape - shape1: {shape1.Name}, pos of shape2: {pos}", { Size: (200, 200), Position: var pos } => $"shape with size 200x200 at position {pos.x}:{pos.y}", Ellipse (var pos, var size) => $"Ellipse with size {size} at position {pos}", Rectangle (_, var size) => $"Rectangle with size {size}", _ => "another shape" };
  39. 39. Indexes and Ranges New Operators ^ Hat Operator .. Range Operator Index und Range & Extensions
  40. 40. Hat Operator int[] arr = { 1, 2, 3 }; int lastItem = arr[^1];
  41. 41. Slice string text1 = "the quick brown fox jumped over the lazy dogs"; string text2 = text1[4..8]; string text3 = text1[^4..^1]; string text4 = text1[10..]; string text5 = text1[..8]; string text6 = text1[..];
  42. 42. Null References Most common .NET Exception NullReferenceException Billion Dollar Mistake 1965 in Algol by Tony Hoare "Billion Dollar Mistake"
  43. 43. Null Conditional Operator (C# 6) • Reduce Null-Checks int? length = customers?.Length; Customer first = customers?[0]; int? count = customers?[0]?.Orders?.Count(); public void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  44. 44. Coalescing Operator (C# 5) • Default values for null int length = customers?.Length ?? 0; public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;
  45. 45. • Helps finding bugs – no guarantee! • Flow analysis - tracks nullable reference variables • Breaks existing code (opt-in) • Nullability implemented with metadata (ignored by downlevel compilers) • string, T non-nullable • string?, T? nullable Nullable Reference Types
  46. 46. Declare Nullable Reference Types • Default to non-nullable • ? to make reference type nullable class Book { public Book(string title, string? isbn = null) { Title = title; Isbn = isbn; } public string Title; // not null public string? Isbn; // may be null }
  47. 47. Using nullable reference type void M1(string? ns) { Console.WriteLine(ns.Length); // compiler warning void M2(string? ns) { if (ns == null) throw new ArgumentNullException(nameof(ns)); Console.WriteLine(ns.Length); // ok, not null ns = null; Console.WriteLine(ns.Length); // compiler warning void M3(string? ns) { if (ns != null) { Console.WriteLine(ns.Length); // ok
  48. 48. Using non-nullable reference type void M1(string ns) { Console.WriteLine(ns.Length); // ok void M2(Book b) { b.Title = null; // warning string isbn = b.Isbn; // warning – may be null string title = b.Title; // ok
  49. 49. Compatibility • Enable this in your own speed // Enable assembly-level [module: NonNullTypes] [NonNullTypes(false)] public class Foo { }
  50. 50. Summary C# 8 Nullable Reference Types Indexes and Ranges Async Streams Magic
  51. 51. Questions?
  52. 52. THANK YOU! https://csharp.christiannagel.com

×