SlideShare a Scribd company logo
C# Today &
Tomorrow
http://stackoverflow.com/research/developer-survey-2015
http://stackoverflow.com/research/developer-survey-2015
http://stackoverflow.com/research/developer-survey-2015
Changing our tune…
Run on Windows
.NET as system component
Run on VM (CLR)
Black box compilers
Edit in Visual Studio
Proprietary
Run everywhere
Deploy with app
Compile to native
Open compiler APIs
Use your favorite editor
Open source
Project Roslyn
“Let’s rewrite the C# and VB compilers and IDE
from scratch!”
• Evolve
• Enable
• Dogfood
The compiler/IDE dichotomy
Compiler
Batch
Throughput
Correctness
Prevent badness
Reactive to what you did
IDE
Incremental
Responsiveness
Error tolerance
Enable goodness
Predictive of what you will do
The Roslyn Compiler API
There should only need to be
one code base in the world
for understanding C#
Other IDEs On other platforms
Custom diagnostics Style, API usage, patterns…
Source transformation Refactorings, fixers, migraters, updaters…
Scripting Batch scripts, hosted code…
Coding in execution REPL, edit-and-continue…
Documentation Hyperlinked API docs, web playgrounds…
Static analysis Code metrics, graphs, telemetry, code querying…
Metaprogramming Source generators, injectors, weavers…
Other language understanding scenarios
Custom analyzers and fixes
Plug in to diagnostic reporting and code fixing
infrastructure
Batch and interactive
“Code-aware libraries”
APIs can ship with analyzers and fixes to guide their users
Toolboxes
Style enforcement, discovery of opportunities
Language evolution explained
Stagnation
C#
Evolution of C#
C# 1
Hello World
C# 2
Generics
C# 3
Queries,
Lambdas
C# 4
Dynamic,
Concurrency
C# 5
Async
C# 6
Avoid
boilerplate
C# 7
???
Demo: REPL and C# 6
C# “7”
Pattern matching
if (o is Point p) { WriteLine($"({p.X}, {p.Y})"); }
if (o is Point p && p.X == 5) { WriteLine($"Y: {p.Y}"); }
if (o is Point(5, var y)) { WriteLine($"Y: {y}"); }
Patterns in switch statements
switch (o)
{
case int i:
WriteLine($"Number {i}");
break;
case Point(int x, int y):
WriteLine($"({x},{y})");
break;
case string s when s.Length > 0:
WriteLine(s);
break;
case null:
WriteLine("<null>");
break;
default:
WriteLine("<other>");
break;
}
Tuples
public (int sum, int count) Tally(IEnumerable<int> values)
{
var s = 0; var c = 0;
foreach (var value in values) { s += value; c++; }
return (s, c);
}
var t = Tally(myValues);
Console.WriteLine($"Sum: {t.sum}, count: {t.count}");
(var s, var c) = Tally(myValues);
Console.WriteLine($"Sum: {s}, count: {c}");
Records
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 (string First, string Last) Deconstruct() => (First, Last);
public bool Equals(Person other) => 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);
…
}
class Person(string First, string Last);
Creating immutable objects
var p1 = new Point { X = 3, Y = 7 };
var p2 = p1 with { X = -p1.X };
Nullable and non-nullable reference types
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!
?

More Related Content

C# Today and Tomorrow

  • 5. Changing our tune… Run on Windows .NET as system component Run on VM (CLR) Black box compilers Edit in Visual Studio Proprietary Run everywhere Deploy with app Compile to native Open compiler APIs Use your favorite editor Open source
  • 6. Project Roslyn “Let’s rewrite the C# and VB compilers and IDE from scratch!” • Evolve • Enable • Dogfood
  • 7. The compiler/IDE dichotomy Compiler Batch Throughput Correctness Prevent badness Reactive to what you did IDE Incremental Responsiveness Error tolerance Enable goodness Predictive of what you will do
  • 8. The Roslyn Compiler API There should only need to be one code base in the world for understanding C#
  • 9. Other IDEs On other platforms Custom diagnostics Style, API usage, patterns… Source transformation Refactorings, fixers, migraters, updaters… Scripting Batch scripts, hosted code… Coding in execution REPL, edit-and-continue… Documentation Hyperlinked API docs, web playgrounds… Static analysis Code metrics, graphs, telemetry, code querying… Metaprogramming Source generators, injectors, weavers… Other language understanding scenarios
  • 10. Custom analyzers and fixes Plug in to diagnostic reporting and code fixing infrastructure Batch and interactive “Code-aware libraries” APIs can ship with analyzers and fixes to guide their users Toolboxes Style enforcement, discovery of opportunities
  • 12. Evolution of C# C# 1 Hello World C# 2 Generics C# 3 Queries, Lambdas C# 4 Dynamic, Concurrency C# 5 Async C# 6 Avoid boilerplate C# 7 ???
  • 15. Pattern matching if (o is Point p) { WriteLine($"({p.X}, {p.Y})"); } if (o is Point p && p.X == 5) { WriteLine($"Y: {p.Y}"); } if (o is Point(5, var y)) { WriteLine($"Y: {y}"); }
  • 16. Patterns in switch statements switch (o) { case int i: WriteLine($"Number {i}"); break; case Point(int x, int y): WriteLine($"({x},{y})"); break; case string s when s.Length > 0: WriteLine(s); break; case null: WriteLine("<null>"); break; default: WriteLine("<other>"); break; }
  • 17. Tuples public (int sum, int count) Tally(IEnumerable<int> values) { var s = 0; var c = 0; foreach (var value in values) { s += value; c++; } return (s, c); } var t = Tally(myValues); Console.WriteLine($"Sum: {t.sum}, count: {t.count}"); (var s, var c) = Tally(myValues); Console.WriteLine($"Sum: {s}, count: {c}");
  • 18. Records 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 (string First, string Last) Deconstruct() => (First, Last); public bool Equals(Person other) => 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); … } class Person(string First, string Last);
  • 19. Creating immutable objects var p1 = new Point { X = 3, Y = 7 }; var p2 = p1 with { X = -p1.X };
  • 20. Nullable and non-nullable reference types 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!
  • 21. ?

Editor's Notes

  1. Evolve: it’s now easier to evolve the languages Enable: it enables a whole ecosystem of code analysis, refactoring tools, and tools that act on code Dogfood: we can roll out new language features and tooling to early adopters for feedback without having to ship VS or compilers
  2. Pace of innovation is not necessarily whenever you get an idea. There’s such a thing as an innovation that comes too soon. The evolution comparison is also interesting because it’s the environment that drives innovation, not random mutations. Horseshoe crab picture by Didier Descouens (Own work) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons Saddleback caterpillar picture by Mary Keim https://www.flickr.com/photos/38514062@N03/9410316517/in/photolist-fkykfv-fkyk58-fpYfpv https://creativecommons.org/licenses/by-nc-sa/2.0/
  3. Launch VS, open REPL (view/other windows/c# interactive) 2+2, Console.WriteLine(“Hello SpaceX”) – Remember, Alt+up arrow to copy a previous statement. CTRL+Enter to execute no matter where the cursor is. using static System.Console; Console.WriteLine(“Hello SpaceX”) <- Roslyn tells you what became unnecessary. Hover to see recommendation. Remove “Console” Interpolating strings should be easy: Add the $ in front of the string, and start introducing expressions: {2016} at the end of the string. Replace expression with {2015+1} Make it reusable next year by writing {DateTime.Now.Year} You can also declare variables in the REPL: var awesomeCompany = “SpaceX”; and then replace the static string. Let’s define a method now: take the previsous code and change it to: string Greeting() {return $”Hello {awesomeCompany} {DateTime.Now.Year}”;} then call Greeting() Change it to a expression-bodied function: string Greeting() => $"Hello { awesomeCompany} { DateTime.Now.Year}"; Let’s look at other C#6 features. First, auto-property initializers: public class Person { public string FirstName { get; } = "Brett"; } new Person().FirstName You can also set such properties from a constructor, which is nice as it removes the need for a private setter that you never don’t need. You can replace the property definition with public string FirstName => "Brett"; Add the following members to the class to introduce the null-coalesce operator: public string LastName { get; set; } public string Initials => FirstName?[0].ToString() + LastName?[0].ToString(); then do new Person().Initials then new Person { LastName = "Morrison" }.Initials We have a new operator that can make a lot of refactoring scenarios more robust: nameof nameof(Person) string Greeting(string awesomeCompany) => $"Hello {nameof(awesomeCompany)} { awesomeCompany } { DateTime.Now.Year }"; Refactoring is going to work inside string interpolation. Index initializers: var numbers = new Dictionary<int, string> { [1] = "One", [42] = "Forty-two“ }; numbers[42] Other C#6 features include await in catch blocks, and “when” conditions on catch.
  4. Closest current equivalent code is var p = o as Point; if (p != null) {… but that gives p too large a scope.
  5. Alternative today is to declare a small class, or have out parameters. The syntax is designed to mirror that of function arguments.
  6. String! Could have been another solution, but would have implied that non-nullable is the exception. Having string? makes nullable strings the exception, as it should have been from the start, but enforcing string without qualifiers to be non-nullable would have been far too breaking. In the end, emitting warnings for failures to check for null is a good compromise as it encourages the right behavior without breaking existing code.