
In April of 2003, C # 1.2 was released, and since then all versions have only the major version.
And now, if you believe the
official roslyn page on github , in version 7.1 and 7.2.
To try version 7.1, you must install pre-release Visual Studio. Download it can be downloaded from the
official site.Going to the properties of the solution, you can select the version of the language.
')

Next, I want to tell you about new language features I liked.
Asynchronous Main (scheduled for version 7.1)
Nowadays, programs that are almost asynchronous are very common.
Until now, Main could be void or int. And it could contain arguments in the form of an array of strings. Now add a few new overloads:
public static Task Main(); public static Task<int> Main(); public static Task Main(string[] args); public static Task<int> Main(string[] args);
Since the CLR does not support asynchronous entrypoints, the compiler itself creates a boilerplate code (that is, it automatically inserts some additional code that allows you to cast void to the Task)
Approximately such code will be generated by the compiler:
async Task<int> Main(string[] args) {
I, as well as many,
expected this functionality in the 7th version of the language.
Literal default (scheduled in version 7.1)
Visual Basic and C # have approximately the same capabilities. But there are certain differences in the languages themselves. Let's say C # has null, and VB.NET has Nothing. So, Nothing can be converted to any system type, representing the default value for this type. It is clear that null does not. Although, the default may well be null.
The expression default (T) is already there and is being applied. Consider an example of its use. Suppose that we have a method that takes an array of strings as a parameter:
void SomeMethod(string[] args) { }
You can run the method and pass it the value of the default string array as follows:
SomeMethod(default(string[]));
But why write default (string []) if you can just write default?
Here, starting with C # 7.1, you can use the default literal. What else can you do with it, except how to pass the default value to the method? For example, it can be used as the value of an optional parameter:
void SomeMethod(string[] args = default) { }
or initialize the variable with the default value:
int i = default;
And it will be possible to check whether the current value is the default value:
int i = 1; if (i == default) { }
What can not be done? The following examples of how the default literal cannot be used:
const int? y = default; if (default == default) if (default is T)
Readonly ref (planned in version 7.2)
When sending structures to methods as by value, the object is copied, which costs resources. And sometimes there is a need to send only the value of the reference object. In this case, the developers send the value by reference ref in order to save memory, but at the same time they write in the comments that the value cannot be changed. Especially often this happens during mathematical operations with vector and matrix objects.
A clear example of what awaits us:
static Vector3 Add (ref readonly Vector3 v1, ref readonly Vector3 v2) {
This function is still in the state of the prototype, but I am sure of its necessity. One suggestion is to use the in keyword instead of ref readonly.
static Vector3 Add (in Vector3 v1, in Vector3 v2) { return new Vector3(v1.X +v2.X, v1.Y + v2.Y, v1.Z + v2.Z); }
Why in, because ref is readonly clearer? And because in shorter.
Interface methods by default (planned in version 8.0)
We will not see these methods soon.
Imagine that there is a class or structure that implements an interface. And now they will be able to inherit the implementation of one method from the interface (!) Or they will have to implement their version of this method.
The very concept of implementation in the interface sounds rather strange. Although Java 8 has default interface methods, and developers using C # also wanted similar functionality for themselves.
This functionality will allow the API author to change the method code for all existing interface implementations.
The example should be clear. Suppose we have such an interface whose SomeMethod method contains an implementation:
interface IA { void SomeMethod() { WriteLine(" SomeMethod IA"); } }
Now create a class that implements the interface:
class C : IA { }
And create an instance of the interface:
IA i = new C();
Now we can call the SomeMethod method:
i.SomeMethod();
Estimated tuple names (planned in version 7.1)
This functionality will allow in some cases not to specify the names of tuples. Under certain conditions, the elements of a tuple can get tentative names.
Example:
Instead of writing (f1: x.f1, f2: x? .F2) you can simply write (x.f1, x? .F2).
The first element of the tuple in this case will get the name f1, and the second f2
Now the tuple would become unnamed (the elements of which can be accessed only by item1, item2 ...)
Estimated names are especially useful when using tuples in LINQ
Negative sides
The main disadvantage of introducing this functionality is compatibility with C # 7.0. Example:
Action y = () => M(); var t = (x: x, y); ty();
But you can put up with this minor compatibility violation, since the period between the release of 7.0 and 7.1 will be small.
Actually, Visual Studio already now when using 7.0 warns that
Tuple element name 'y' is inferred. Please use language version 7.1 or greater to inferred name.
Full sample code:
class Program { static void Main(string[] args) { string x = "demo"; Action y = () => M(); var t = (x: x, y); ty();
If you are using .NET 4.6.2 and below, in order to try the example you need to install the NuGet System.ValueTuple package.