- PVSM.RU - https://www.pvsm.ru -

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn

C# постоянно развивается. Весной вышла уже седьмая версия. В этой статье будет обзор поддержки последних фич C# в CodeRush for Roslyn. Про C# 7.0 уже было несколько публикаций на хабре, поэтому основное внимание именно на то, как это поддерживается в CodeRush for Roslyn.

Бонусом, в конце статьи, дадим рецепт для тех, кто по каким то причинам не хочет использовать новые языковые фичи.

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 1

Task-like возвращаемые типы асинхронных методов

Если раньше асинхронный метод мог возвращать только типы Task или Task<T>, то теперь возможно объявить собственные Task-like типы, которые можно использовать в возвращаемых значениях асинхронных методов.

Во-первых, давайте проверим как работают фичи внутри асинхронного метода, который возвращает Task-like тип. Например, для метода с одним параметром попробуем вызвать Exit Method Contract [1]:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 2

Как видим, CodeRush for Roslyn корректно определил, что return-оператор должен быть пустым и не должен содержать никакого выражения, т.к. в данном случае возвращаемый тип не является универсальным (не содержит параметров типа). Другие фичи, которые генерируют return-операторы также работают корректно. В качестве примера, давайте посмотрим как отработает шаблон [2] "r", который вызывает Smart Return, внутри асинхронного метода:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 3

В этом случае CodeRush правильно распознал, что в return-операторе должно содержаться выражение типа ArgumentKind и вставил соответствующее значение по-умолчанию.

Второй момент — это фичи, которые используют await-выражения с вызовом асинхронного метода, возвращающего Task-like тип. Как видно на следующем скриншоте, CodeRush правильно определяет тип таких await-выражений:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 4

Кортежи значений

Пожалуй, это нововведение в спецификациях языков претендует на роль самого востребованного. Теперь с помощью удобного синтаксиса можно объявлять типы, являющиеся кортежами нескольких значений. Можно задавать как просто типы элементов, так и их имена. Для будущих релизов у нас есть несколько идей по наиболее обширной поддержке кортежей: определять и удалять неиспользуемые пункты, менять пункты местами, использовать кортежи в рефакторинге Convert to Tuple [3] и др. Пока же имеется поддержка кортежей в уже имеющихся фичах. Продемонстрируем это на примере рефакторинга Add Parameter [4]:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 5

Рефакторинг корректно распарсил введённое значение как кортеж из SortingKind и SortingOrder и в качестве дефолтного значения подставил кортеж из дефолтных значений этих типов.

В качестве ещё одного примера продемонстрируем работу фичи Smart Return, которая вызывается раскрытием шаблона r:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 6

Как видим, CodeRush for Roslyn использует имена для переменных кортежа, если они были объявлены.

Вложенные локальные функции

Порой возникает необходимость написания вспомогательной функции использование, которой ограниченно определённым методом. В C# 7 возможно объявить локальную функцию прямо в теле метода. Локальные функции схожи с лямбда-выражениями, но зачастую код использование локальных функций является более наглядным и понятным.

Во-первых, мы обновили фичу Naming Assistant [5] чтобы она работала с локальными функциями:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 7

А еще, уже знакомый Add Parameter [4] тоже теперь работает с новым синтаксисом:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 8

Рефакторинг правильно нашёл декларацию и все ссылки и добавил параметр в нужные позиции.

Расширение использования expression-body и throw-expression

Думаю, что многим пришлось по душе использование expression-body в C# 6, теперь список элементов, где он может быть расширен акцессорами свойств, конструкторами и деструкторами. Рефакторинг Use Expression Body [6] доступен на новых элементах:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 9

Также и обратные данному рефакторингу Expand Method [7] и Expand Accessor [8] доступны, если использован новый синтакс.

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 10

Use Expression Body доступен теперь и в тех случаях, когда в теле метода/акcессора отсутствует имплементация и присутствует лишь вызов исключения. С появлением throw-expression запись таких методов можно сделать короче и нагляднее:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 11

Ещё один случай, где throw-expression повышает наглядность кода — это тернарные операторы. Теперь if/else-выражение, в котором в зависимости от условия либо вызывается исключении, либо возвращается/присваивается какое-то значение, можно заменить одним выражение с тернарным оператором. Поможет в этом рефакторинг Compress to Ternary Expression [9]:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 12

Обратный рефакторинг Expand Ternary Expression [9] конечно же также будет доступен на выражениях с throw-expression:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 13

Сопоставление с образцом

Тоже очень мощное нововведение, которое, уверен, уже полюбилось многим пользователям. Оно позволяет в операторах if и case проверить, что переменная является объектом определённого типа и тут же объявить переменную этого типа, избегая лишнего кастинга. В case-операторах в дополнение к этому можно осуществить дополнительные проверки в when-выражении.

В данном разделе мы тоже пока не воплотили все свои идеи. В качестве примера того, что уже имеется, продумонстрируем работу фичи Declare Class [10] на case-выражении, в котором использован новый синтакс:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 14

В данном случае CodeRush for Roslyn корректно определил, что здесь используется шаблон типа, а также сразу задекларировал свойство, используемое в when-выражении. Давайте теперь отладим данный метод при этом включим CodeRush Debug Visualizer [11]:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 15

Когда отладчик доходит до switch-оператора, Debug Visualizer вычисляет выражения во всех case-ветках и отображает какая из них будет выполняться в данном случае, делая код остальных веток более блеклым. Это делает отладку кода более наглядной и удобной, показывая какой код будет выполняться на следующем шаге.

Возврат по ссылке

Теперь ссылка на переменную может использоваться не только в параметре, но и в возращаемом типе метода. Также можно объявлять локальные переменные, которые будут содержать ссылку на переменную.

Возьмём связку из двух уже знакомых нам фич: Smart Return и Declare Method и посмотрим как они отработают в методе, который возвращает значение по ссылке:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 16

Smart Return подставил ключевое слово ref, поскольку return-оператор должен содержать ref-выражение в данном случае. Declare Method, определив, что метод вызывается в ref-выражении, корректно объявил возвращаемый тип как ref int.

Бинарные литералы

Теперь значения каких-то констант в коде можно задавать, используя двоичный код. Это может быть удобным в перечислениях. CodeRush имеет в своём арсенале фичу, которая позволяет ускорить и упростить задачу добавления нового элемента — Smart Duplicate Line [12]. Достаточно нажать Shift + Enter и CodeRush добавит новый элемент, выделив текстовыми полями те элементы, которые потребуют изменений:

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 17

И обещанный бонус

Мало кто знает, но на уровне проекта можно выбирать версию языка. CodeRush for Roslyn учитывает опцию Build | Advanced | Language Version.

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 18

Например, если поставить C# 4.0, то контекстное меню изменится, потому что интерполяцию строк придумали в C# 6.0.

О поддержке языковых фич C# в Visual Studio и в CodeRush for Roslyn - 19

Но мы не просто скрываем неподдерживаемые пункты меню по условию, мы реализуем полноценную поддержку нужной версии языка на в том числе на уровне генерации кода.

Например, если в проекте стоит версия C# 6.0, то Declare Comparison members из Declare Menu [13] сгенерит код таким образом:

// ...
Class1 other = obj as Class1;
if (other == null) {
   throw new ArgumentException(nameof(obj) + " is not a " + nameof(Class1));
}
// ...

А в C# 3.0, например, nameof() еще не было, и код будет таким:

// ...
Class1 other = obj as Class1;
if (other == null) {
    throw new ArgumentException("obj is not a Class1");
}
// ...

За счет использования штатных парсеров студии CodeRush for Roslyn одинаково хорошо поддерживает как новые возможности C#, так и старые. CodeRush значительно расширяет возможности Visual Studio не замедляя ее. Особенно это заметно на серьезных enterprise-проектах с большим объемом кода.

Скачать попробовать CodeRush for Roslyn можно на нашем сайте [14].

Автор: xtraroman

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/net/261981

Ссылки в тексте:

[1] Exit Method Contract: https://documentation.devexpress.com/CodeRushForRoslyn/115562/Coding-Assistance/Code-Providers/Contract-Providers/Exit-Method-Contract

[2] шаблон: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115904

[3] Convert to Tuple: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115476

[4] Add Parameter: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115688

[5] Naming Assistant: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument118373

[6] Use Expression Body: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115599

[7] Expand Method: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115371

[8] Expand Accessor: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115460

[9] Compress to Ternary Expression: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115431

[10] Declare Class: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115689

[11] CodeRush Debug Visualizer: https://documentation.devexpress.com/#CodeRushForRoslyn/CustomDocument115769

[12] Smart Duplicate Line: https://documentation.devexpress.com/CodeRushForRoslyn/115903/Coding-Assistance/Typing-Helpers#dupln

[13] Declare Menu: https://documentation.devexpress.com/CodeRushForRoslyn/118647/Coding-Assistance/Declare-Menu

[14] на нашем сайте: https://www.devexpress.com/Products/CodeRush/download.xml

[15] Источник: https://habrahabr.ru/post/334664/