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# - What's next

274 views

Published on

Planned features for C# 8

Published in: Software
  • Be the first to comment

  • Be the first to like this

C# - What's next

  1. 1. C# - What’s next? @christiannagel
  2. 2. C# Strategie
  3. 3. Laufende Erweiterungen Geänderte Bedürfnisse erfüllen
  4. 4. Agenda C# Strategie C# Today C# Future
  5. 5. Christian Nagel • Training • Coaching • Consulting • Development • Microsoft MVP • www.cninnovation.com • csharp.christiannagel.com
  6. 6. Schnell Innovationen einführen Aber im Geist von C#
  7. 7. Ziele mit C# 7.1, 7.2, 7.3 • Garbage Collection vermeiden • Kopieren vermeiden • "Safe" Code Sicherer, effizienter Code • Zusätzliche Möglichkeiten Mehr Freiheiten • "Sag es kürzer" Weniger Code
  8. 8. C# 8 Magisch
  9. 9. C# 7.x Today
  10. 10. C# 7.0 Tuples & Deconstruction Pattern Matching Expressions everywhere Reference Semantics
  11. 11. Tuples • Werte unterschiedlicher Typen kombinieren • 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. 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;
  15. 15. 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; }
  16. 16. 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 };
  17. 17. C# 7 Point Releases • Sicherer, effizienter Code • Mehr Freiheiten • Weniger Code
  18. 18. C# 8
  19. 19. State Proposal Discussed/Decision in LDM Prototype Implementation in Progress Implemented
  20. 20. State: Implemented • Default literal deconstruction • Alternative interpolated verbatim strings (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
  21. 21. State: In Progress • Generic attributes • Relax ordering ref and partial modifiers • Null coalescing assignment • Async streams • Ranges • Records 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
  22. 22. State: Prototype • Caller expression attribute • Target-typed new • Pattern-based using • Default interface methods • Nullable reference type • 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");
  23. 23. Default Interface Methods Ändern von Interfaces ohne Breaking Changes Traits – Wiederverwendbarkeit von Methoden in unabhängigen Klassen Basiert auf Java's Default Methods
  24. 24. 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); }
  25. 25. Default Interface Methods Allowed Modifiers private, protected, internal, public, virtual, abstract, override, sealed, static, extern
  26. 26. Default Interface Methods Mehrfachvererbung mit 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(); }
  27. 27. 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(); }
  28. 28. Default Interface Methods Re-Abstract interface I0 { void M(); } interface I2 : I0 { override void M(); } interface I1 : I0 { override void M() => Console.WriteLine("I1"); }
  29. 29. Async Streams • async/await liefert ein Ergebnis • Async Streams erweitert async/await mit Stream von Ergebnissen • Asynchronous Datenquellen die vom Consumer kontrolliert werden • Alternative zu System.Reactive
  30. 30. Async Streams • IAsyncDisposable • IAsyncEnumerable • IAsyncEnumerator public interface IAsyncDisposable { Task DisposeAsync(); } public interface IAsyncEnumerable<out T> { IAsyncEnumerator<T> GetAsyncEnumerator(); } public interface IAsyncEnumerator<out T> : IAsyncDiposable { Task<bool> MoveNextAsync(); T Current { get; } }
  31. 31. Using Async Streams • foreach await IAsyncEnumerator<T> enumerator = enumerable.GetAsyncEnumerator(); try { while (await enumerator.MoveNextAsync()) { Use(enumerator.Current); } } finally { await enumerator.DisposeAsync(); } foreach await (var i in enumerable) { Use(i); }
  32. 32. 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"); } }
  33. 33. Async Streams Open Questions • LINQ • ~600 neue Methoden wären erfoderlich • Interactive Extensions (Ix) implementiert viele • => Support Community extend Ix • Integration mit IObservable<T> • Integration auf Library- Ebene
  34. 34. Records Einfachere Deklaration für Klassen und Structs (Immutable) Caller-Receiver Parameters With Expressions
  35. 35. Declare Records public struct Pair(object First, object Second);
  36. 36. Record Implementation • Implements • IEquatable • GetHashCode • Deconstruct • With public struct Pair(object First, object Second); public struct Pair : IEquatable<Pair> { public object First { get; } public object Second { get; } public Pair(object First, object Second) { this.First = First; this.Second = Second; } public bool Equals(Pair other) => Equals(First, other.First) && Equals(Second, other.Second); public override bool Equals(object other) => (other as Pair)?.Equals(this) == true; public override int GetHashCode() => (First?.GetHashCode()*17 + Second?.GetHashCode()).GetValueOrDefault(); public Pair With(object First = this.First, object Second = this.Second) => new Pair(First, Second); public void Deconstruct(out object First, out object Second) { First = this.First; Second = this.Second; } } var p1 = new Pair("one", "two"); var p2 = p1.With(First: "alpha");
  37. 37. Caller-Receiver Parameter class Point { public readonly int X; public readonly int Y; public Point With(int x = this.X, int y = this.Y) => new Point(x, y); //... } var p = new Point(3, 4); p = p.With(x: 1);
  38. 38. With Expression var p = new Point(3, 4); p = p with { x = 1 }; // p = p.With(x: 1);
  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. More Uses • switch, foreach switch (codePoint) { case 1536..1541: break; foreach (var item in 3..5) {
  43. 43. Patterns Extended • Always match Discard Pattern • Match für Property Werte Property Pattern • Match für innere Properties Recursive Pattern • Moderner switch Syntax switch Expression
  44. 44. 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"; } }
  45. 45. 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" } };
  46. 46. 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" };
  47. 47. Null References Most common .NET Exception NullReferenceException Billion Dollar Mistake 1965 in Algol by Tony Hoare "Billion Dollar Mistake"
  48. 48. 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));
  49. 49. Coalescing Operator (C# 5) • Default values for null int length = customers?.Length ?? 0; public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;
  50. 50. Nullable Reference Types • Hilft finden von Bugs, aber keine Garantie! • 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
  51. 51. 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 }
  52. 52. 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
  53. 53. 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
  54. 54. Compatibility • Enable this in your own speed // Enable assembly-level [module: NonNullTypes] [NonNullTypes(false)] public class Foo { }
  55. 55. Summary C# 8 Nullable Reference Types Indexes and Ranges Async Streams Magic
  56. 56. Questions?
  57. 57. What's next – Try it out! • https://github.com/dotnet/csharplang/wiki/Nullable- Reference-Types-Preview • Visual Studio 2017 15.5-15.8 (funktioniert nicht mit 15.8.4, 15.8.5) Nullable Reference Types • https://github.com/dotnet/csharplang/wiki/vNext- Preview • Visual Studio 2017 15.5-15.7 Patterns und Ranges • https://github.com/dotnet/roslyn Andere Features
  58. 58. More Information • https://github.com/ProfessionalCSharp • https://csharp.christiannagel.com • https://www.cninnovation.com • Training & Coaching
  59. 59. Thank you!

×