KEMBAR78
Next .NET and C# | PPTX
What’s next for .NET Core and C#
Bertrand Le Roy
Agenda
• Tooling
• .NET Standard
• C#
.NET Core everywhere
• Windows
• macOS
• Ubuntu, Debian, CentOS, RHEL, openSUSE, Fedora, …
• Docker
• X86, x64, ARM
Tooling
• Visual Studio 2017
• OmniSharp: VS Code, vim, emacs, Sublime, etc.
• Visual Studio for Mac
• JetBrains Rider
• CLI: x-plat, focused on building code for both humans and
machines…
Project system
• project.json will be gone for good with the 1.0 of the tooling
• New and improved csproj
• Small
• Easy to manually edit
• Globs – easier merges!
• No GUIDs
• Lower concept count
• Integrated package references
• Easily migrated from project.json
• One project system to rule Xamarin, Mono, .NET Core, .NET Framework
• All the power of MSBuild
Default console app template…
… with a package
Default library template
Introducing the SDK
• Contains all the tasks and targets for working with Core code
• Shared between CLI, Visual Studio, Visual Studio for Mac, VS
Code (OmniSharp)
Shared SDK component
Visual Studio VS Code
.NET Core
Command Line
tools
CLI commands
dotnet build --output [path]
the driver verb (command) verb arguments
Core commands
• dotnet new
• dotnet restore
• dotnet run
• dotnet build
• dotnet publish
• dotnet pack
• dotnet test
CRUD & advanced commands
• dotnet add/list/remove reference
• dotnet add/list/remove package
• dotnet sln add/list/remove
• dotnet msbuild
• dotnet nuget
• dotnet vstest
• … and your own commands, distributed as NuGet packages or
added to the path
.NET before .NET Standard
Compilers Languages Runtime components
COMMON INFRASTRUCTURE
.NET before .NET Standard
Compilers Languages Runtime components
COMMON INFRASTRUCTURE
.NET after .NET Standard
Compilers Languages Runtime components
COMMON INFRASTRUCTURE
.NET after .NET Standard
Compilers Languages Runtime components
COMMON INFRASTRUCTURE
What is .NET Standard?
• A spec: .NET Standard is to .NET what POSIX is to Unix
public class DotNetCore : IDotNetStandard { … }
• A set of APIs that all .NET platforms have to implement
• A class library provided as a NuGet package that provides the
façade that .NET code can compile against
Versioning .NET Standard
• Higher version incorporates all
previous
• Concrete .NET platforms
implement a specific version of
the standard, and can run all
code targeting versions up to
that number
2.0
1.6
1.3
1.0
What’s new in .NET Standard 2.0?
• More than double the APIs
• Compatibility with .NET Framework libraries: your code may
already be cross-platform…
Version #APIs Growth %
1.6 13,501
2.0 32,638 +142%
APIs in .NET Standard 2.0
Primitives • Collections • Reflection • Interop • LinqCORE
Threads • Thread Pool • TasksTHREADING
Files • Compression • MMFIO
Sockets • Http • Mail • WebSocketsNETWORKING
BinaryFormatter • Data Contract • XMLSERIALIZATION
XLinq • XML Document • XPath • Schema • XSLXML
Abstractions • Provider Model • DataSetDATA
http://apisof.net
http://stackoverflow.com/research/developer-survey-2016#technology-most-popular-technologies
Most “popular” technologies
http://stackoverflow.com/research/developer-survey-2016#technology-most-loved-dreaded-and-wanted
Most “loved” technologies
C# - State of the Union
C#
1,000,000’s
Millions
C# 7.0 recap
static void Main(string[] args)
{
object[] numbers =
{ 0b1, 0b10, new object[] { 0b100, 0b1000 }, // binary literals
0b1_0000, 0b10_0000 }; // digit separators
var (sum, count) = Tally(numbers); // deconstruction
WriteLine($"Sum: {sum}, Count: {count}");
}
C# 7.0 recap
static (int sum, int count) Tally(object[] values) // tuple types
{
var r = (s: 0, c: 0); // tuple literals
void Add(int s, int c) { r.s += s, r.c += c; } // local functions
foreach (var v in values)
{
switch (v) // switch on any value
{
case int i: // type patterns
Add(i, 1);
break;
case object[] a when a.Length > 0: // case conditions
var t = Tally(a);
Add(t.sum, t.count);
break;
}
}
return r;
}
What’s ahead
Many ideas, and some stand out as clearly worthwhile
Smaller, more frequent language versions that are opt-in for the cutting edge
Major features requiring framework or runtime evolution
Design tenets
The language embraces new concepts
Common paths become easier
Code runs faster or uses less memory
Bugs are prevented
Recursive patterns
if (o is Point(_, var y)) { WriteLine($"Y: {y}"); }
if (o is Point { Y: var y }) { WriteLine($"Y: {y}"); }
Pattern matching expressions
var s = match (o)
{
int i => $"Number {i}",
case Point(int x, int y) => $"({x},{y})",
string s when s.Length > 0 => s,
null => "<null>",
_ => "<other>"
};
Tuples in patterns
state = match (state, request)
{
(Closed, Open) => Opened,
(Closed, Lock) => Locked,
(Opened, Close) => Closed,
(Locked, Unlock) => Closed,
_ => throw new InvalidOperationException(…)
}
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!
Async streams and disposables
IAsyncEnumerable<Person> people = database.GetPeopleAsync();
foreach await (var person in people)
{
// use person
}
using await (IAsyncDisposable resource = await store.GetRecordAsync(…))
{
// use resource
}
Default implementations
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset() => throw new InvalidOperationException("Reset not supported");
}
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
new T Current { get; }
object IEnumerator.Current => Current;
}
Records and discriminated unions
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 void Deconstruct(out string first, out string last)
{
first = First; last = Last;
}
public bool Equals(Person other) => other != null && 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);
…
}
record Person(string First, string Last);
Primary constructors
public class AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ILogger<AccountController> logger) : Controller()
{
public UserManager<ApplicationUser> UserManager => userManager;
public SignInManager<ApplicationUser> SignInManager => signInManager;
///...
}
Creating immutable objects
var p1 = new Point { X = 3, Y = 7 };
var p2 = p1 with { X = -p1.X };
Extension everything
extension Enrollee extends Person
{
// static field
static Dictionary<Person, Professor> enrollees = new();
// instance method
public void Enroll(Professor supervisor) { enrollees[this] = supervisor; }
// instance property
public Professor Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null;
// static property
public static ICollection<Person> Students => enrollees.Keys;
// instance constructor
public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); }
}
Questions?

Next .NET and C#

  • 1.
    What’s next for.NET Core and C# Bertrand Le Roy
  • 2.
  • 3.
    .NET Core everywhere •Windows • macOS • Ubuntu, Debian, CentOS, RHEL, openSUSE, Fedora, … • Docker • X86, x64, ARM
  • 4.
    Tooling • Visual Studio2017 • OmniSharp: VS Code, vim, emacs, Sublime, etc. • Visual Studio for Mac • JetBrains Rider • CLI: x-plat, focused on building code for both humans and machines…
  • 5.
    Project system • project.jsonwill be gone for good with the 1.0 of the tooling • New and improved csproj • Small • Easy to manually edit • Globs – easier merges! • No GUIDs • Lower concept count • Integrated package references • Easily migrated from project.json • One project system to rule Xamarin, Mono, .NET Core, .NET Framework • All the power of MSBuild
  • 6.
  • 7.
    … with apackage
  • 8.
  • 9.
    Introducing the SDK •Contains all the tasks and targets for working with Core code • Shared between CLI, Visual Studio, Visual Studio for Mac, VS Code (OmniSharp) Shared SDK component Visual Studio VS Code .NET Core Command Line tools
  • 10.
    CLI commands dotnet build--output [path] the driver verb (command) verb arguments
  • 11.
    Core commands • dotnetnew • dotnet restore • dotnet run • dotnet build • dotnet publish • dotnet pack • dotnet test
  • 12.
    CRUD & advancedcommands • dotnet add/list/remove reference • dotnet add/list/remove package • dotnet sln add/list/remove • dotnet msbuild • dotnet nuget • dotnet vstest • … and your own commands, distributed as NuGet packages or added to the path
  • 13.
    .NET before .NETStandard Compilers Languages Runtime components COMMON INFRASTRUCTURE
  • 14.
    .NET before .NETStandard Compilers Languages Runtime components COMMON INFRASTRUCTURE
  • 15.
    .NET after .NETStandard Compilers Languages Runtime components COMMON INFRASTRUCTURE
  • 16.
    .NET after .NETStandard Compilers Languages Runtime components COMMON INFRASTRUCTURE
  • 17.
    What is .NETStandard? • A spec: .NET Standard is to .NET what POSIX is to Unix public class DotNetCore : IDotNetStandard { … } • A set of APIs that all .NET platforms have to implement • A class library provided as a NuGet package that provides the façade that .NET code can compile against
  • 18.
    Versioning .NET Standard •Higher version incorporates all previous • Concrete .NET platforms implement a specific version of the standard, and can run all code targeting versions up to that number 2.0 1.6 1.3 1.0
  • 19.
    What’s new in.NET Standard 2.0? • More than double the APIs • Compatibility with .NET Framework libraries: your code may already be cross-platform… Version #APIs Growth % 1.6 13,501 2.0 32,638 +142%
  • 20.
    APIs in .NETStandard 2.0 Primitives • Collections • Reflection • Interop • LinqCORE Threads • Thread Pool • TasksTHREADING Files • Compression • MMFIO Sockets • Http • Mail • WebSocketsNETWORKING BinaryFormatter • Data Contract • XMLSERIALIZATION XLinq • XML Document • XPath • Schema • XSLXML Abstractions • Provider Model • DataSetDATA http://apisof.net
  • 21.
  • 22.
  • 23.
    C# - Stateof the Union C# 1,000,000’s Millions
  • 24.
    C# 7.0 recap staticvoid Main(string[] args) { object[] numbers = { 0b1, 0b10, new object[] { 0b100, 0b1000 }, // binary literals 0b1_0000, 0b10_0000 }; // digit separators var (sum, count) = Tally(numbers); // deconstruction WriteLine($"Sum: {sum}, Count: {count}"); }
  • 25.
    C# 7.0 recap static(int sum, int count) Tally(object[] values) // tuple types { var r = (s: 0, c: 0); // tuple literals void Add(int s, int c) { r.s += s, r.c += c; } // local functions foreach (var v in values) { switch (v) // switch on any value { case int i: // type patterns Add(i, 1); break; case object[] a when a.Length > 0: // case conditions var t = Tally(a); Add(t.sum, t.count); break; } } return r; }
  • 26.
    What’s ahead Many ideas,and some stand out as clearly worthwhile Smaller, more frequent language versions that are opt-in for the cutting edge Major features requiring framework or runtime evolution
  • 27.
    Design tenets The languageembraces new concepts Common paths become easier Code runs faster or uses less memory Bugs are prevented
  • 28.
    Recursive patterns if (ois Point(_, var y)) { WriteLine($"Y: {y}"); } if (o is Point { Y: var y }) { WriteLine($"Y: {y}"); }
  • 29.
    Pattern matching expressions vars = match (o) { int i => $"Number {i}", case Point(int x, int y) => $"({x},{y})", string s when s.Length > 0 => s, null => "<null>", _ => "<other>" };
  • 30.
    Tuples in patterns state= match (state, request) { (Closed, Open) => Opened, (Closed, Lock) => Locked, (Opened, Close) => Closed, (Locked, Unlock) => Closed, _ => throw new InvalidOperationException(…) }
  • 31.
    Nullable and non-nullablereference 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!
  • 32.
    Async streams anddisposables IAsyncEnumerable<Person> people = database.GetPeopleAsync(); foreach await (var person in people) { // use person } using await (IAsyncDisposable resource = await store.GetRecordAsync(…)) { // use resource }
  • 33.
    Default implementations public interfaceIEnumerator { object Current { get; } bool MoveNext(); void Reset() => throw new InvalidOperationException("Reset not supported"); } public interface IEnumerator<out T> : IDisposable, IEnumerator { new T Current { get; } object IEnumerator.Current => Current; }
  • 34.
    Records and discriminatedunions 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 void Deconstruct(out string first, out string last) { first = First; last = Last; } public bool Equals(Person other) => other != null && 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); … } record Person(string First, string Last);
  • 35.
    Primary constructors public classAccountController( UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, ILogger<AccountController> logger) : Controller() { public UserManager<ApplicationUser> UserManager => userManager; public SignInManager<ApplicationUser> SignInManager => signInManager; ///... }
  • 36.
    Creating immutable objects varp1 = new Point { X = 3, Y = 7 }; var p2 = p1 with { X = -p1.X };
  • 37.
    Extension everything extension Enrolleeextends Person { // static field static Dictionary<Person, Professor> enrollees = new(); // instance method public void Enroll(Professor supervisor) { enrollees[this] = supervisor; } // instance property public Professor Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null; // static property public static ICollection<Person> Students => enrollees.Keys; // instance constructor public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); } }
  • 38.