Новые возможности в C# 6

C# logo20 июля состоялся выпуск 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).
  • Конструктор без параметров для структур.

Добавить комментарий