20 июля состоялся выпуск Visual Studio 2015 в которую входит C# 6. Давайте посмотрим на возможности, которые предоставляет разработчикам новая версия этого языка программирования. |
Инициализация
Инициализация свойств
Наконец появилась возможность инициализации свойств (в том числе и только для чтения) в объявлении:
public class CSharp6Features
{
public int CurrentVersion { get; set; } = 6;
public int LatestVersion { get; } = 6;
}
Кроме того, свойства только с get можно инициализировать в конструкторе класса. Указывать для этого private set не нужно.
public class CSharp6Features
{
public int LatestVersion { get; }
public CSharp6Features()
{
this.LatestVersion = 6;
}
}
Объявление методов и свойств с помощью выражений
В С# 6 разрешено использовать выражения для объявления методов:
public bool IsLatest(int version) => version == this.LatestVersion;
// Эквивалентно записи
public bool IsLatest(int version)
{
return version == this.LatestVersion;
}
Аналогично можно поступать и со свойствами:
public string CurrentTime => DateTime.Now.ToLongTimeString();
// Эквивалентно созданию свойства только для чтения
public string CurrentTime
{
get { return DateTime.Now.ToLongTimeString(); }
}
Индексы при инициализации
С# 6 позволяет гораздо нагляднее указывать индексы при инициализации:
var someInstance = new Dictionary<int, string>
{
[1] = "Option 1",
[2] = "Option 2"
};
Методы-расширения для инициализации коллекций
Уже давно в C# есть возможность инициализировать коллекции при создании экземпляра. Например:
var intList = new List<int> { 1, 2, 3 };
При этом неявно вызывается метод Add() для добавления каждого их перечисленных значений. При этом их тип должен соответствовать типу аргумента Add().
C# 6 разрешает создавать собственные методы-расширения Add(), которые будут использованы при инициализации. Например, вот так можно присвоить числовые значения в List<string>:
public static class CollectionExtensions
{
public static void Add(this ICollection<string> col, int i)
{
col.Add(i.ToString());
}
}
// Теперь следующий код будет корректным:
var strList = new List<string> { 1, 2, 3 };
Таким образом можно инициализировать коллекции любым типом и модифицировать логику инициализации.
Исключения
Фильтры исключений
Фильтры исключений добавляют условия, при которых срабатывают блоки catch(). Синтаксис:
try { }
catch (...) when (условие) { ... }
Например:
try
{
...
}
catch(DomainException ex) when (ex.ExceptionCode == 42)
{
...
}
В данном примере при возникновении DomainException управление перейдет в блок catch только если ExceptionCode равен 42.
Async в блоках catch и finaly
Начиная с 6 версии C#, разрешено использовать асинхронные функции в блоках catch и finaly:
try
{
// ...
}
catch (Exception exception)
{
await LogAsync(exception);
}
finally
{
await ReleaseResourcesAsync();
}
Операторы и возможнос��и языка
Упрощенный вызов статических методов
C# 6 позволяет упростить запись вызова статических методов, указав их класс в качестве параметра using static.
using static System.Console;
public class UsingStaticDemo
{
public void Foo()
{
// Вместо Console.WriteLine("Hello"); можно использовать
WriteLine("Hello");
}
}
(На мой взгляд, эта возможность ведет к путанице вызовов статических методов и методов самого класса. Особенно если не используется this для выделения последних.)
Оператор nameof()
Выражение nameof() позволяет получить имя указанного класса или свойства в виде текста:
var className = nameof(CSharp6Features); // вернет "CSharp6Features"
var propertyName = nameof(instance.LatestVersion); // вернет "LatestVersion"
Интерполяция строк
Переменные теперь возможно указывать прямо внутри строк. При этом сама строка записывается как $"…", а переменные выделяются c помощью фигурных скобок {varName}. Кроме того, разрешено использовать форматирование. Например:
var str1 = $"Current version: {this.CurrentVersion}";
var str2 = $"Current date: {DateTime.UtcNow.Date}";
var str3 = $"Current Time: {DateTime.UtcNow:hh:mm:ss}";
Null-оператор
Null-оператор используется для получения значений свойств, экземпляр класса которых может быть равен null. Его форма записи имеет вид: variableName?.propertyName. При этом если variableName равно null, то результат также будет null. В противном случае будет возвращено значение свойства propertyName.
int? currentVersion = runtime?.CSharpFeatures?.CurrentVersion;
Как можно догадаться, это сокращённая формой записи для:
if (runtime != null && runtime.CSharpFeatures != null)
currentVersion = runtime.CSharpFeatures.CurrentVersion;
else
currentVersion = null;
Были завялены, но не вошли в 6 версию
- Первичный конструктор класса (primary constructor).
- Конструктор без параметров для структур.