C # is constantly evolving. In the spring came the seventh version. This article will review the support for the latest C # features in CodeRush for Roslyn. About C # 7.0, there have already been several publications on Habré, so the focus is on how it is supported in CodeRush for Roslyn.
Bonus, at the end of the article, we give a recipe for those who for some reason do not want to use new language features.
If earlier the asynchronous method could return only the Task or Task <T> types, then it is now possible to declare your own Task- like types that can be used in the returned values of the asynchronous methods.
First, let's check how the features work inside the asynchronous method, which returns a Task- like type. For example, for a method with one parameter, try calling Exit Method Contract :
As you can see, CodeRush for Roslyn correctly determined that the return operator should be empty and should not contain any expression, since in this case, the return type is not universal (does not contain type parameters). Other features that generate return operators also work correctly. As an example, let's see how the "r" template , which calls Smart Return , will work out inside an asynchronous method:
In this case, CodeRush correctly recognized that the return operator should contain an expression of the type ArgumentKind and insert the corresponding default value.
The second point is features that use await expressions with a call to an asynchronous method that returns a Task- like type. As can be seen in the following screenshot, CodeRush correctly determines the type of such await expressions:
Perhaps this innovation in the specifications of languages claims to be the most sought after. Now, using convenient syntax, you can declare types that are tuples of multiple values. You can set as just the types of elements, and their names. For future releases, we have several ideas on the most extensive support for tuples: identify and delete unused points, swap points, use tuples in Convert to Tuple refactoring, etc. In the meantime, there are support for tuples in existing features. Let us demonstrate this with the example of Add Parameter refactoring:
Refactoring correctly parsed the entered value as a tuple from SortingKind and SortingOrder and substituted the tuple from the default values of these types as the default value.
As another example, we will demonstrate the Smart Return feature, which is caused by the expansion of the r template:
As you can see, CodeRush for Roslyn uses the names for the variables of the tuple, if they were declared.
Sometimes it becomes necessary to write an auxiliary function using, which is restricted to a specific method. In C # 7, it is possible to declare a local function directly in the method body. Local functions are similar to lambda expressions, but often the code using local functions is more intuitive and understandable.
First, we updated the Naming Assistant feature so that it works with local functions:
And yet, the already familiar Add Parameter also now works with the new syntax:
Refactoring correctly found the declaration and all references and added the parameter to the desired position.
I think that many people liked the use of expression-body in C # 6, now the list of elements where it can be expanded by property accessors, constructors and destructors. Refactoring Use Expression Body is available on new items:
Inverse to this refactoring, Expand Method and Expand Accessor are also available if new syntax is used.
Use Expression Body is available now also in cases when there is no implementation in the method / accessor body and only an exception call is present. With the appearance of a throw-expression, writing such methods can be made shorter and clearer:
Another case where a throw-expression improves the visibility of the code is the ternary operators. Now the if / else expression, in which, depending on the condition, either an exception is called or some value is returned / assigned, you can replace with one expression with a ternary operator. Compress to Ternary Expression refactoring will help in this:
The reverse refactoring of Expand Ternary Expression will of course also be available on expressions with a throw-expression:
It is also a very powerful innovation, which, I am sure, has already been loved by many users. It allows in the if and case statements to check that a variable is an object of a certain type and immediately declare a variable of this type, avoiding unnecessary casting. In case- operators, in addition to this, additional checks in the when- expression can be performed.
In this section, we also have not yet embodied all their ideas. As an example of what already exists, let's illustrate the work of the Declare Class feature on a case expression that uses the new syntax:
In this case, CodeRush for Roslyn correctly determined that a type pattern was used here, and immediately declared the property used in the when- expression. Let's now debug this method while turning on the CodeRush Debug Visualizer :
When the debugger reaches the switch- operator, the Debug Visualizer evaluates the expressions in all case branches and displays which of them will be executed in this case, making the code for the other branches fainter. This makes code debugging more intuitive and convenient, showing what code will be executed in the next step.
Now the variable reference can be used not only in the parameter, but also in the return type of the method. You can also declare local variables that will contain a reference to the variable.
Let's take a bunch of two familiar features: Smart Return and Declare Method and see how they work in the method that returns the value by reference:
Smart Return has substituted the ref keyword, since the return statement must contain a ref expression in this case. The Declare Method , determining that the method is being invoked in a ref-expression, declared the correct type of ref SyntaxNode .
Now the values of some constants in the code can be set using a binary code. This can be handy in listings. CodeRush has in its arsenal a feature that allows you to speed up and simplify the task of adding a new element - Smart Duplicate Line . It is enough to press Shift + Enter and CodeRush will add a new element, selecting the text fields for those elements that will require changes:
Few people know, but at the project level, you can choose the language version. CodeRush for Roslyn considers Build | Advanced | Language Version .
For example, if you put C # 4.0, the context menu changes, because the interpolation of the lines was invented in C # 6.0.
But we do not just hide unsupported menu items by condition, we implement full-fledged support for the necessary version of the language, including at the level of code generation.
For example, if the project is version C # 6.0, then the Declare Comparison members from the Declare Menu will generate the code like this:
// ... Class1 other = obj as Class1; if (other == null) { throw new ArgumentException(nameof(obj) + " is not a " + nameof(Class1)); } // ...
And in C # 3.0, for example, nameof () was not yet, and the code would be like this:
// ... Class1 other = obj as Class1; if (other == null) { throw new ArgumentException("obj is not a Class1"); } // ...
Due to the use of regular parsers of CodeRush for Roslyn studio, it equally well supports both the new features of C # and the old ones. CodeRush greatly enhances Visual Studio without slowing it down. This is especially noticeable on serious enterprise-projects with a large amount of code.
You can download a trial version of CodeRush for Roslyn on our website .
Source: https://habr.com/ru/post/334664/
All Articles