next .net and c#
TRANSCRIPT
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…<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp1.0</TargetFramework> </PropertyGroup></Project>
… with a package<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp1.0</TargetFramework> </PropertyGroup>
<ItemGroup> <PackageReference Include="Newtonsoft.JSON" Version="9.0.1" />
</ItemGroup></Project>
Default library template<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework> </PropertyGroup></Project>
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 .NET FRAMEWORK .NET CORE XAMARIN
APP
MO
DELS
BASE
LIBR
ARIE
S
Compilers Languages Runtime components
COMMON INFRASTRUCTURE
Base Class Library Core Library Mono Class Library
ASP.NET
Windows FormsWPF UWP
ASP.NET Core
iOSAndroid
OS X
.NET before .NET Standard .NET FRAMEWORK .NET CORE XAMARIN
APP
MO
DELS
BASE
LIBR
ARIE
S
Compilers Languages Runtime components
COMMON INFRASTRUCTURE
Base Class Library Core Library Mono Class Library
ASP.NET
Windows FormsWPF UWP
ASP.NET Core
iOSAndroid
OS XDifficult to reuse skills• Need to master 3+1 base class libraries
Difficult to reuse code• Need to target a small common denominator
Difficult to innovate• Need implementations on each platform
CHALLENGES
.NET after .NET Standard .NET FRAMEWORK .NET CORE XAMARIN
APP
MO
DELS
BASE
LIBR
ARIE
S
Compilers Languages Runtime components
COMMON INFRASTRUCTURE
Base Class Library Core Library Mono Class Library
ASP.NET
Windows FormsWPF UWP
ASP.NET Core
iOSAndroid
OS X
.NET STANDARDOne BCL to rule them all
.NET after .NET Standard .NET FRAMEWORK .NET CORE XAMARIN
APP
MO
DELS
BASE
LIBR
ARIE
S
Compilers Languages Runtime components
COMMON INFRASTRUCTURE
Base Class Library Core Library Mono Class Library
ASP.NET
Windows FormsWPF UWP
ASP.NET Core
iOSAndroid
OS X
.NET STANDARDOne BCL to rule them all
Reuse skills• Master one library, not a platform
Reuse code• Big surface area - no small common denominator
Faster innovation• .NET Standard can grow without updating platforms
BENEFITS
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 • Linq
CORE
Threads • Thread Pool • TasksTHREADING
Files • Compression • MMFIO
Sockets • Http • Mail • WebSocketsNETWORKING
BinaryFormatter • Data Contract • XMLSERIALIZATION
XLinq • XML Document • XPath • Schema • XSL
XML
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• The lingua franca of .NET• Lead with C#• Keep up with (and move) industry state of the art• Focus on improvements for all C# developers• Innovate judiciously and responsibly
C# 1,000,000’sMillions
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 recapstatic (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 aheadNo clear shape of future versions yetMany ideas, and some stand out as clearly worthwhile
“Point” releases C# 7.1, 7.2, …Smaller, more frequent language versions that are opt-in for the cutting edge
C# 8.0, 9.0, …Major features requiring framework or runtime evolution
Design tenetsExpressivenessThe language embraces new concepts
ConvenienceCommon paths become easier
PerformanceCode runs faster or uses less memory
SafetyBugs 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 expressionsvar 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 patternsstate = 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 typestring s; // Non-nullable reference type
n = null; // Sure; it's nullables = null; // Warning! Shouldn’t be null!s = n; // Warning! Really!
WriteLine(s.Length); // Sure; it’s not nullWriteLine(n.Length); // Warning! Could be null!
if (n != null) { WriteLine(n.Length); } // Sure; you checkedWriteLine(n!.Length); // Ok, if you insist!
Async streams and disposablesIAsyncEnumerable<Person> people = database.GetPeopleAsync();
foreach await (var person in people) { // use person}
using await (IAsyncDisposable resource = await store.GetRecordAsync(…)) { // use resource}
Default implementationspublic 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 unionsclass 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 constructorspublic 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 everythingextension 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?