Clean up your code with C#6

880 vues

Publié le

Now that C#6 is officially available, most people will have a look to new features. The purpose of this talk is not only to show you the new feature but also, and mostly to show you how it can improve your code to write it in a better, smaller and more readable way

Publié dans : Logiciels
0 commentaire
3 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
880
Sur SlideShare
0
Issues des intégrations
0
Intégrations
14
Actions
Partages
0
Téléchargements
7
Commentaires
0
J’aime
3
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Clean up your code with C#6

  1. 1. >< nextprevious C#6A cleaner code
  2. 2. Clean up your code! >< nextprevious Philosophy design No New Big features … but many small ones to to improve your code
  3. 3. Clean up your code! >< nextprevious Put C#6 In context Let’s see how to improve our code with less boiler plate and more meanings
  4. 4. >< nextprevious The language C#1 async/await ? var, anonymous, Lambdas, auto- properties, line Generics, partials, iterators, nullables C#2 C#4 C#3 C#5 C#6 History dynamic, optional parameters 2002 2005 2007 20152012 2010
  5. 5. >< nextprevious Developers should write their code to fit in a slide
  6. 6. News 01 Using Static classes why bother with static class names? 02 03 04 >< nextprevious String Interpolation because string.format sucks Getter only properties because un-meaningful boiler plate auto-properties initializers because creating a backing field for properties only don’t make sense
  7. 7. >< nextprevious Using Static 01 using System; public class Code { public void LogTime(string message) { Console.Write(DateTime.Now); Console.WriteLine(message); } }
  8. 8. >< nextprevious Using Static 01 using static System.Console; using static System.DateTime; public class Code { public void Print(string message) { Write(Now); WriteLine(message); } }
  9. 9. >< nextprevious Using Static 01 Console.Write(DateTime.Now); Write(Now); From a very technical line You moved to a natural language reading friendly sentence using static allows removal of technical boilerplate
  10. 10. >< nextprevious String Interpolation 02 public void UserMessagesLog( string message, User user) { var messageToLog = string.Format("[{0}] {1} - {2}", DateTime.Now, user.Name, message); Console.WriteLine(messageToLog); } }
  11. 11. >< nextprevious String Interpolation 02 public void UserMessagesLog( string message, User user) { var messageToLog = $"[{DateTime.Now}] {User.Name} - {message}" Console.WriteLine(messageToLog); } }
  12. 12. >< nextprevious String Interpolation 02 string.Format("[{0}] {1} - {2}", DateTime.Now, user.Name, message); $"[{DateTime.Now}] {User.Name} - {message}" sounds good enough for small strings, But… we’re stupid, when you read the code, there will be a context switch to interpret the result of your string if the value is not in the place you write it!
  13. 13. >< nextprevious String Interpolation 02 public void UserMessagesLog( string message, User user) { var messageToLog = $"[{DateTime.Now}] {User.Name} - {message}" Console.WriteLine(messageToLog); } } Why waiting 15 years for that?
  14. 14. >< nextprevious Getter only properties 03 public class Post { private string title; public string Title { get{return title;} } public Post(string title) { this.title=title } } C#2
  15. 15. >< nextprevious Getter only properties 03 public class Post { public string Title { get;private set;} public Post(string title) { Title=title } } C#3
  16. 16. >< nextprevious Getter only properties 03 public class Post { public string Title { get;} public Post(string title) { Title=title } } C#6
  17. 17. >< nextprevious AutoProperties initializers 04 public class Post { private string id="new-post"; public string Id { get{return id;} } public Post() { } } C#2
  18. 18. >< nextprevious AutoProperties initializers 04 public class Post { public string Id {get;private set;} public Post() { Id="new-post"; } } C#3
  19. 19. >< nextprevious AutoProperties initializers 04 public class Post { public string Id {get;} = "new-post"; } C#6
  20. 20. News 05 Expression bodied properties because one expression is enough 06 07 08 >< nextprevious Expression bodied methods too much braces for a one expression function Index initializers because initializer shortcuts are great Null conditional operators if null then null else arg…
  21. 21. >< nextprevious Expression bodied props 05 public class Post { private DateTime created = DateTime.Now; public DateTime Created { get{return created;} } public TimeSpan Elapsed { get { return (DateTime.Now-Created); } } } C#3
  22. 22. >< nextprevious Expression bodied props 05 public class Post { public DateTime Created {get;} = DateTime.Now; public TimeSpan Elapsed => (DateTime.Now-Created); } C#6
  23. 23. >< nextprevious Expression bodied props 05 public class Post { public DateTime Created {get;} = DateTime.Now; public DateTime Updated => DateTime; } C#6 Spot the difference {get;} = value is affected once for all, stored in an hidden backing field => represents an expression, newly evaluated on each call
  24. 24. >< nextprevious Expression Bodied Methods 06 public class Post { public string Title {get;set;} public string BuildSlug() { return Title.ToLower().Replace(" ", "-");  } } C#3
  25. 25. >< nextprevious Expression Bodied Methods 06 public class Post { public string Title {get;set;} public string BuildSlug() { return Title.ToLower().Replace(" ", "-");  } } C#3 never been frustrated to have to write this {return} boilerplate since you use the => construct with lambdas?
  26. 26. >< nextprevious Expression Bodied Methods 06 public class Post { public string Title {get;set;} public string BuildSlug() => Title .ToLower() .Replace(" ", "-"); } C#6
  27. 27. >< nextprevious Index initializers 07 public class Author { public Dictionary<string,string> Contacts {get;private set;}; public Author() { Contacts = new Dictionary<string,string>(); Contacts.Add("mail", "demo@rui.fr"); Contacts.Add("twitter", "@rhwy"); Contacts.Add("github", "@rhwy"); } } C#2
  28. 28. >< nextprevious Index initializers 07 public class Author { public Dictionary<string,string> Contacts {get;} = new Dictionary<string,string>() { ["mail"]="demo@rui.fr", ["twitter"]="@rhwy", ["github"]="@rhwy" }; } C#6
  29. 29. >< nextprevious Index initializers 07 public class Author { public Dictionary<string,string> Contacts {get;} = new Dictionary<string,string>() { {"mail","demo@rui.fr"}, {"twitter","@rhwy"}, {"github","@rhwy"} }; } C#3
  30. 30. >< nextprevious Null Conditional Operators 08 public class Post { //"rui carvalho" public string Author {get;private set;}; //=>"Rui Carvalho" public string GetPrettyName() { if(Author!=null) { if(Author.Contains(" ")) { string result; var items=Author.Split(" "); forEach(var word in items) { result+=word.SubString(0,1).ToUpper() +word.SubString(1).ToLower() + " "; } return result.Trim(); } } return Author; } } C#3
  31. 31. >< nextprevious Null Conditional Operators 08 public class Post { //"rui carvalho" public string Author {get;private set;}; //=>"Rui Carvalho" public string GetPrettyName() => (string.Join("", Author?.Split(' ') .ToList() .Select( word=> word.Substring(0,1).ToUpper() +word.Substring(1).ToLower() + " ") )).Trim(); C#6
  32. 32. >< nextprevious Null Conditional Operators 08 public class Post { //"rui carvalho" public string Author {get;private set;}; //=>"Rui Carvalho" public string GetPrettyName() => (string.Join("", Author?.Split(' ') .ToList() .Select( word=> word.Substring(0,1).ToUpper() +word.Substring(1).ToLower() + " ") )).Trim(); C#6 We have now one expression only but maybe not that clear or testable ?
  33. 33. >< nextprevious Null Conditional Operators 08 public string PrettifyWord (string word) => word.Substring(0,1).ToUpper() +word.Substring(1).ToLower() + " "; public IEnumerable<string> PrettifyTextIfExists(string phrase) => phrase? .Split(' ') .Select( PrettifyWord); public string GetPrettyName() => string .Join("",PrettifyTextIfExists(Author)) .Trim(); C#6 Refactoring ! We have now 3 small independent functions with Names and meanings
  34. 34. News 09 Exception filters not new in .Net 10 11 12 >< nextprevious nameof Operator consistent refactorings await in catch who never complained about that? and in finally the last step
  35. 35. News 09 Exception filters not new in .Net 10 11 12 >< nextprevious nameof Operator consistent refactorings await in catch who never complained about that? and in finally the last step these ones are just goodimprovements but not thatimportant for our code readability
  36. 36. >< nextprevious Exception Filters 09 try { //production code } catch (HttpException ex) { if(ex.StatusCode==500) //do some specific crash scenario if(ex.StatusCode==400) //tell client that he’s stupid } catch (Exception otherErrors) { // ... } C#2
  37. 37. >< nextprevious Exception Filters 09 try { //production code } catch (HttpException ex) when (ex.StatusCode == 500) { //do some specific crash scenario } catch (HttpException ex) when (ex.StatusCode == 400) { //tell the client he’s stupid } catch (Exception otherException) { // ... } C#6
  38. 38. >< nextprevious nameof Operator 10 public string SomeMethod (string word) { if(word == null) throw new Exception("word is null"); return word; } C#3
  39. 39. >< nextprevious nameof Operator 10 public string SomeMethod (string text) { if(word == null) throw new Exception("word is null"); return word; } C#3 Refactoring arg, information lost!
  40. 40. >< nextprevious nameof Operator 10 public string SomeMethod (string word) { if(word == null) throw new Exception( $"{nameof(word)} is null"); return word; } C#6 parameter name is now pure code & support refactoring
  41. 41. >< nextprevious await in catch 11 try { return await something(); } catch (HttpException ex) { error = ex; } return await CrashLogger.ServerError(error); C#5
  42. 42. >< nextprevious await in catch 11 try { await something(); } catch (HttpException ex) { await CrashLogger.ServerError(ex); } C#6
  43. 43. >< nextprevious await in finally 12 try { return await Persistence.Query(query); } catch (PersistenceException ex) { await CrashLogger.ServerError(ex); } finally { await Persistence.Close(); } C#6
  44. 44. >< nextprevious To Finish C#6 helps to be more functional & write cleaner code by removing lots of boilerplate! refactoring to small functions, add new words to your app vocabulary
  45. 45. >< nextprevious Thanks @rhwy ncrafts.io altnet.fr rui.io

×