Обзор новых элементов C# 6.0

В сети находится огромное количество информации по этой теме и все достаточно разрозненно. Хотелось прежде всего для себя систематизировать и обозначить новые возможности языка. Некоторые вещи являются синтаксическим сахаром, некоторые являются действительно новыми фичами. Хотя в свете возможностей предоставляемых Roslyn, понятие о «сахаре» и новых фичах несколько размывается. Ведь можно модифицировать язык и создавать свои диалекты. Так что возможно скоро большие команды будут использовать свои варианты языка. Или нет. Но это отдельная большая тема (вспоминается просто Jetbrains с их Resharper). Доступность описываемых фич описана на странице https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status. Большая часть всех фич уже доступна и вызывает положительные эмоции. Хотя, честно сказать, не всё из того, что помечено как «должно работать» работает. Например, индексированные члены в словаре что-то не завелись, хотя остальное все работало как надо.

Активизация экспериментального компилятора

Для того, чтобы описываемые штуки завелись, необходимо использовать VS2014 cRoslynSDK, или же VS2013 с SDK, RoslynSDK. После того как все компоненты были установлены, можно создать новый проект, открыть файл проекта (.CSPROJ) в текстовом редакторе и добавить в конфигурацию сборки строку:

<LangVersion>experimental</LangVersion>

Обратите внимание, что именно с маленькой буквы надо писать «experimental», иначе не работает. Конечно, это будет поправлено ближе к релизу. После таких нехитрых приготовлений можно начинать эксперименты.

Краткий список нововведений

  • Exists: Already shipped in previous release
  • Done: Implemented for this release
  • Planned: Intended for this release
  • Maybe: Possibly intended for this release
  • Withdrawn: Probably not in this release
  • No: Not intended for this release

 

Feature Example C#
Primary constructors class Point(int x, int y) { … } Done
Auto-property initializers public int X { get; set; } = x; Done
Getter-only auto-properties public int Y { get; } = y; Done
Using static members using System.Console; … Write(4); Done
Dictionary initializer new JObject { [«x»] = 3, [«y»] = 7 } Done
Indexed member initializer new JObject { $x = 3, $y = 7 } Withdrawn
Indexed member access
  1. $name = c.$first + » » + c.$last;
Withdrawn
Declaration expressions int.TryParse(s, out var x); Done
Await in catch/finally try … catch { await … } finally { await … } Done
Exception filters catch(E e) if (e.Count > 5) { … } Done
Typecase Select Case o : Case s As String : … No
Guarded cases Select Case i : Case Is > 0 When i Mod 2 = 0 No
Partial interfaces Partial Interface I1 Exists
Binary literals 0b00000100 Planned
Digit separators 0xEF_FF_00_A0 Planned
Expression-bodied members public double Dist => Sqrt(X * X + Y * Y); Planned
Event initializers new Customer { Notify += MyHandler }; Planned
Null propagation customer?.Orders?[5]?.$price Done
Semicolon operator (var x = Foo(); Write(x); x * x) Maybe
Private protected private protected string GetId() { … } Withdrawn
Params IEnumerable int Avg(params IEnumerable<int> numbers) { … } Planned
Constructor Inference new Tuple(3, «three», true); Maybe
String interpolation «\{p.First} \{p.Last} is \{p.Age} years old.» Maybe
TryCast for nullable var x = TryCast(u, Integer?) Exists
Implicit implementation Class C : Implicitly Implements I Exists
NameOf operator string s = nameof(Console.Write); Planned

Подробнее