📜 ⬆️ ⬇️

Investigate the minor features of C # 7

C # 7 adds a number of new features and focuses on data consumption, simplifying code and performance. The biggest features have already been considered - tuples , local functions , pattern matching and throw expressions . But there are other new opportunities, both large and small. All of them are combined to make the code more efficient and understandable so that everyone will be happy and productive.

Let's look at the other features of the new version of C #. So! Let's start!

Out variables


Currently, in C #, using out parameters is not as flexible as we would like. Before calling a method with out parameters, you first need to declare the variables to pass to the method. Since usually these variables are not initialized (since they will be rewritten by the method), you cannot use var to declare them, therefore you must specify the full type:
')
public void PrintCoordinates(Point p) { int x, y; // have to "predeclare" p.GetCoordinates(out x, out y); WriteLine($"({x}, {y})"); } 

In C # 7, out variables are entered. They allow you to declare variables right on the spot where they are passed as out arguments :

 public void PrintCoordinates(Point p) { p.GetCoordinates(out int x, out int y); WriteLine($"({x}, {y})"); } 

Notice that the variables rise to the outer scope in the closing block, so the subsequent line can use them.

Since out variables are declared directly as arguments to out parameters, the compiler can infer their type (if there are no conflicting overloads), so you can use var instead of type when declaring:

 p.GetCoordinates(out var x, out var y); 

Typically, out parameters are used in Try ... patterns, where a logical return value indicates success, and out parameters carry the results obtained:

 public void PrintStars(string s) { if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); } else { WriteLine("Cloudy - no stars tonight!"); } } 

You can also use “ wildcards ” in out parameters in the form of _ to ignore out parameters that are not needed:

 p.GetCoordinates(out int x, out _); // I only care about x 

Please note that you can omit the type declaration with “ wildcards ”.

 string inputDate = ""; if (DateTime.TryParse(inputDate, out DateTime dt)) { //  dt } 

The question is, what if the conversion of a string to a DateTime variable is unsuccessful, and we still try to use the output value?

The variable will have a default value .

Literal improvements


C # 7 allows you to use the “ _ ” character as a delimiter of digits inside numeric literals:

 var d = 123_456; var x = 0xAB_CD_EF; 

You can put this character anywhere between the numbers just as many times as necessary to improve readability. It does not affect the value.

The separator can be used with the types byte , int , long , decimal , float and double :

 public const long BillionsAndBillions = 100_000_000_000; public const double AvogadroConstant = 6.022_140_857_747_474e23; public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M; 

In addition, C # 7 presents binary literals . Now you can write the number in binary form.

 var b = 0b101010111100110111101111; 

0b at the beginning of a constant means that the number is written in binary format.

You can also use the delimiter character, which will undoubtedly improve the readability of the literal.

 var b = 0b1010_1011_1100_1101_1110_1111; 

Discharge separator cannot stand at the end or at the beginning of a literal

 byte a = 0b_0000_0001; //INVALID: Digit separator cannot be at the start or end of the value byte b = 0b1_0000_0001; //INVALID: 257 doesn't fit in a byte byte c = 0b0_0000_0001; //VALID: 1 fits into a byte just fine 

Ref returns and locals


Just as you can pass method parameters by reference (with the ref modifier), you can now also return them by reference, and also save them by reference in local variables.

 public ref int Find(int number, int[] numbers) { for (int i = 0; i < numbers.Length; i++) { if (numbers[i] == number) { return ref numbers[i]; // return the storage location, not the value } } throw new IndexOutOfRangeException($"{nameof(number)} not found"); } int[] array = { 1, 15, -39, 0, 7, 14, -12 }; ref int place = ref Find(7, array); // aliases 7's place in the array place = 9; // replaces 7 with 9 in the array WriteLine(array[4]); // prints 9 

This is useful for returning specific fields from large data structures. For example, a game may contain its data in a large pre-distributed array of structures (to avoid pauses when garbage collection). Now methods can return a link directly to a structure through which the caller can read and modify it.

There are some security restrictions:


Returned generic types in async methods


Until now, async methods in C # must either return void , Task or Task ‹T› . C # 7 allows you to define other types in such a way that they can be returned from the asynchronous method. The return type must still match the asynchronous pattern, which means that the GetAwaiter method must be available. A concrete example: a new type ValueTask has been added to the .NET Framework, allowing to use this new language feature

Since Task and Task ‹T are reference types, allocating memory in performance-affecting segments (especially when allocating memory in limited cycles) can seriously degrade performance. Support for generic types of return values ​​allows you to return a small significant type instead of a reference type, thereby preventing excessive memory allocation.

 class Program { static Random rnd; static void Main() { Console.WriteLine($"You rolled {GetDiceRoll().Result}"); } private static async ValueTask GetDiceRoll() { Console.WriteLine("...Shaking the dice..."); int roll1 = await Roll(); int roll2 = await Roll(); return roll1 + roll2; } private static async ValueTask Roll() { if (rnd == null) rnd = new Random(); await Task.Delay(500); int diceRoll = rnd.Next(1, 7); return diceRoll; } } 

Conclusion


Use the new features of C #, because they facilitate development, save time and increase the readability of the code. This article ends the series of articles on the C # 7 version. All questions of interest, please in the comments or in a personal. I will answer you for sure. Thanks to all!

Source: https://habr.com/ru/post/350710/


All Articles