O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

77o dotNETZone Meetup: Pattern matching expressions. One small step for one language...

82 visualizações

Publicada em

Pattern matching expressions may seem like a small change. And yet, they allow far safer and easier code right now, while setting the stage for further functional enhancements in C# 9. Let's talk about how pattern matching exceptions can simplify your current code today and enable patterns you couldn't really use before

Publicada em: Software
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

77o dotNETZone Meetup: Pattern matching expressions. One small step for one language...

  1. 1. Pattern Matching Expressions One small step for one language …
  2. 2. Μα τί με νοιάζει?
  3. 3. Μα είναι μόνο για .NET Core 3? • Όχι, παίζει και σε .NET Standard 2.0 • <LangVersion>8.0</LangVersion> • Μερικά έξτρα packages για async streams κλπ • Microsoft.Bcl.AsyncInterfaces • Microsoft.Bcl.HashCode
  4. 4. Μα τι σκέφτεται ο Torgersen ? Ήπιε χαλασμένη βότκα? Ή μήπως …
  5. 5. Η C# γίνεται functional • Όπως και η JavaScript, Java, Python • Κάθε νέο feature κι ένα βήμα • Αρχικά LINQ • C# 7: Pattern matching • C# 8: Exhaustive matching • C# 9: Discriminated unions, records • Interoperability με άλλες γλώσσες, ειδικά σε Android (Default Members) • Καλούδια από άλλες γλώσσες
  6. 6. Functional Programming! • Functors and Monads and rings and … Wait a minute! • Ομάδες και Δακτύλιοι!
  7. 7. Τι καινούριο υπάρχει σε pattern matching? • Switch (Pattern) expressions. Ωραία κι από μόνα τους • Property patterns • Positional patterns – deconstructors για μας τους θνητούς • Tuple patterns
  8. 8. Pattern Expressions static string Display(object o) => o switch { Point p when p.X == 0 && p.Y == 0 => "origin", Point p => $"({p.X}, {p.Y})", _ => "unknown” }; • Exhaustive matching – Αν κάτι λείπει, ο compiler γκρινιάζει • Όχι αρκετά έξυπνο ακόμα – περιμένουμε Discriminated Unions στη C# 9
  9. 9. Property Patterns static string Display(object o) => o switch { Point { X: 0, Y: 0 } p => "origin", Point { X: var x, Y: var y } p => $"({x}, {y})", _ => "unknown" }; • «Ανοίγει» τα properties και ταιριάζει τις τιμές • Δεν χρειάζονται όλα • Exhaustive matching
  10. 10. Τόσο σημαντικό είναι το exhaustive matching? • Ο compiler ελέγχει ότι καλύψαμε όλες τις περιπτώσεις • Αν προσθέσουμε νέους τύπους ή συνδυασμούς, ο compiler το βρίσκει • Κώδικας ο οποίος απλά δεν επιτρέπει λάθη • Σα να τρέχεις Unit test την ώρα του compilation • Το discard ( _ ) είναι κακό! Κάτι σαν catch{}
  11. 11. “Positional” patterns - Deconstructors static string Display(object o) => o switch { Point(0, 0) => "origin", Point(var x, var y) => $"({x}, {y})", _ => "unknown" }; • Βγάζει τιμές μέσω του deconstructor και τις ταιριάζει • Αν δεν θέλουμε κάποια τιμή, _ για discard • Exhaustive matching
  12. 12. Uses Ωραία τα τρυκ αλλά τί μας νοιάζει?
  13. 13. State machines
  14. 14. State Machine - Code static State ChangeState(State current, Transition transition, bool hasKey) => (current, transition) switch { (Opened, Close) => Closed, (Closed, Open) => Opened, (Closed, Lock) when hasKey => Locked, (Locked, Unlock) when hasKey => Closed, _ => throw new InvalidOperationException($"Invalid transition") };
  15. 15. State Machine – Ακόμα και … static State ChangeState(State current, Transition transition, bool hasKey) => (current, transition, hasKey) switch { (Opened, Close, _ ) => Closed, (Closed, Open, _ ) => Opened, (Closed, Lock, true) => Locked, (Locked, Unlock, true) when hasKey => Closed, _ => throw new InvalidOperationException($"Invalid transition") };
  16. 16. Uncertain input (parsers, readers) • Getting a DateTime from Excel. • Could be DateTime, string, number DateTime GetDate(this IExcelDataReader reader,int idx) { return reader.GetValue(idx) switch { DateTime date =>date, string s => DateTime.Parse(s,CultureInfo.GetCultureInfo(“de-DE")), double d => DateTime.FromOADate(d), _ => throw new InvalidCastException() }; }
  17. 17. Multi-value results Απ’ την παραγωγή (DateTime date,bool ok) GetDate(this IExcelDataReader reader,int idx) { return reader.GetValue(idx) switch { DateTime date => (date,true), …, _ => default }; }
  18. 18. Multi-value return types Στην κατανάλωση if(reader.GetDate(3) is (var date,true)) { Console.WriteLine(“{0:s}”,date); } • No Go players were harmed during the creation of this sample • Doesn’t protect from truly evil devs is (var date,_)
  19. 19. If not null, then what? • Με Nullable reference types τι κάνουμε με properties που λείπουν στο JSON? • Πάααλι null? Class Customer { public string Name{get;set;} public Address Address{get;set;} }
  20. 20. If not null, then what ? Options in F# type Option<'a> = | Some of 'a // valid value | None
  21. 21. If not null, then what? Options readonly struct Option<T> { public readonly T Value {get;} public readonly bool IsSome {get;} public readonly bool IsNone =>!IsSome; public Option(T value)=> (Value,IsSome)=(value,true); public void Deconstruct(out T value)=> (value)=(Value); } static class Option { public static Option<T> Some<T>(T value) => new Option<T>(value); public static Option<T> None<T>() => default; ... }
  22. 22. If not null, then what? Using Options static string Test(Option<MyClass> opt = default) { return opt switch { Option<MyClass> { IsNone: true } => "None", Option<MyClass> (var v) => $"Some {v.SomeText}” }; }
  23. 23. DTO with Option • Option is struct, default is None • Satisfies Non-nullable checks Class Customer { public string Name{get;set;} public Option<Address> Address {get;set;} }
  24. 24. OptionConverter για System.Text.Json internal class OptionConverter<T> : JsonConverter<Option<T>> where T : class { public override Option<T> Read(ref Utf8JsonReader reader, …) => Option.Some(JsonSerializer.Deserialize<T>(ref reader)); public override void Write(Utf8JsonWriter writer, Option<T> value, …) { switch (value) { case Option<T> {IsNone:true} : break; case Option<T> (var v) : JsonSerializer.Serialize(writer,v,options); break; } } }
  25. 25. Fluent calls, Pipelines and async flows • Call Chaining • Fluent APIs • Async streams • Channels • Dataflows • How do we handle errors without breaking the flow?
  26. 26. Τι κάνουμε εδώ? Βαράμε ή … async IAsyncEnumerable<int> Sqrt(IAsyncEnumerable<int> input) { await foreach(var i in input) { //What about NEGATIVES? return Math.Sqrt(i); } }
  27. 27. Σε F#,Rust κλπ, Either/Maybe/Result • Discriminated Unions • Exhaustive matching • Όχι ακόμη στην C# 8 [<Struct>] type Result<'T,'TError> = | Ok of ResultValue :’T | Error of ErrorValue. :'TError match res1 with | Ok req -> printfn "My request was valid! Name: %s Email %s" req.Name req.Em | Error e -> printfn "Error: %s" e
  28. 28. Προσέγγιση interface IResult<TResult,TError>{} struct Success<TResult,TError> :IResult<TResult,TError> { public TResult Value{get;} public Success(TResult value) { Value=value; } } struct Error<TResult,TError> :IResult<TResult,TError> { public TError ErrorValue {get;} public Error(TError error) { ErrorValue=error; } }
  29. 29. Χρήση – Non-exhaustive IResult<int,string> Sqrt(IResult<int,string> input) { return input switch { Error<int,string> e =>e, Success<int,string> {Value:var v} s when v<0 => new Error<int,string>("Negative"), Success<int,string> {Value:var v} _ => new Success<int,string>((int)Math.Sqrt(v)) _ => throw new ArgumentException(); // }; }
  30. 30. Τι κάνουμε εδώ? … async IAsyncEnumerable<IResult<int,string>> Sqrt(IAsyncEnumerable<IResult<int,string> input) { await foreach(var i in input) { return Sqrt(i); } }
  31. 31. Railway Oriented programming Scott Wlaschin
  32. 32. Συμπεράσματα • Απλούστερος Κώδικας – Ταμάμ! • Όχι αρκετά γνώριμα ακόμα • Ασφαλέστερος κώδικας • Βάση για νέα patterns και idioms • «Δανειζόμαστε» ιδέες από F#, άλλες γλώσσες
  33. 33. Resources • Railway Oriented Programming, Scott Wlaschin • F# for Fun and Profit • C# in Depth, Fourth edition, Jon Skeet • Pluralsight: What’s New in C# 8.0 and .NET Core 3.0 • Pattern Matching – C# Guide
  34. 34. Κλήρωση • 1 άδεια για ένα από τα προϊόντα της JetBrains • Χρησιμοποιήστε τη για να μας δώσει κι άλλες

×