📜 ⬆️ ⬇️

New C # 7.2. Span and Memory



Good day,% habrauser%! Faced with the problem of slowing down the system while transferring using variables stored in the stack, I went to Google and found an excellent solution to using the Span <T> collection, which was added in the C # 7.2 version. But I noticed that in RuNet there are almost no articles devoted to this update. Therefore, I decided to sketch a short article that may be useful for beginners.

Added new access modifier private protected


This access modifier provides the ability to call only derived classes within the same assembly. In contrast to the previously implemented protected internal modifier, which allowed access as derived classes, so to all and classes of the same assembly.

Non-final named arguments


In C #, so-called named arguments can be used. They allow the developer not to memorize the required order of the method parameters, if the parameter name is specified manually. Let's look at the signature of this method:
')
public void Print(string text, int size, string title) 

We can refer to this method as usual.

 Print("Hello, World!", 24, "Hi!"); 

And we can use named arguments and set parameters in arbitrary order. Or set part of the arguments in order (such arguments are called positional), and set the rest with the name.

 Print(size: 24, title: "Hi!", text: "Hello, World!"); Print("Hello, World!", title: "Hi!", size: 24); 

So, there used to be a limitation that after the named arguments there could only be other named arguments. If a positional argument was specified after the named argument, an error message was displayed. Now, if the argument is in the correct position, after the named argument, then the program will work correctly.

 Print(text: "Hello, World!", 24, "Hi!"); 

But at the same time, if the positional order has been violated, an error message will be displayed. Data code will not work, because despite the fact that the size is in place, the title and text are interchanged.

 Print(title: "Hi!", 24, text: "Hello, World!"); // . 

Initial underscores in numeric literals


C # has already implemented the ability to use binary and hexadecimal literals using the underscore "_" delimiter, so previously using it as the first character of the literal was prohibited. Now this restriction has been removed.

 int i = 0b1101_0111; //     . int i = 0b_1101_0111; //    . 

Using references for data types stored by value


For a start it is worth remembering that there are two types of data:


Moreover, if a significant type was transferred to a method, then a new copy of it was created, so it was impossible to change the original variable inside the method if access modifiers (ref) were not used. But if a reference type was passed to the method, then the object was not copied, and the change of the object in the method changed the original object.

Here there is one not obvious problem, since when a significant type is transferred to a method, a new copy is created each time, a system slowdown and excessive use of memory occurs. This is especially true for bulk structures that are stored in the stack. Imagine a recursive method call, passing a 20-field structure as an argument ... Therefore, in the new version of the language, steps were taken to optimize work with variables stored in value.

An in modifier has been added, which indicates that a significant type should be passed by reference, but this imposes a restriction that it cannot be changed inside the method.

 private int Sum(in int value1, in int value2); 

Since the struct is also stored on the stack, the use of the readonly modifier is added to it, which is essentially an analogue of

 readonly public struct ReadonlyPosition { public ReadonlyPosition(int x, int y) { X = x; Y = y; } public int X { get; } public int Y { get; } private static readonly ReadonlyPosition _position = new ReadonlyPosition(); public static ref ReadonlyPosition Position => ref _position; } 

A ref struct modifier has been added that indicates that the structure is passed by reference, and should be processed with a stack allocation.

The ref accessonly access modifier has also been added, which indicates that the value is returned by reference, but it is not allowed to change the corresponding variable.

Finally, the Span <T> type was added, which allows you to create a collection of data stored on the stack, but accessed by reference. The Memory <T> type is an extension of the Span <T> type and is used for thread-safe access by reference to the collection stored on the stack.

This concludes my small overview of the update. I hope someone will find this information useful. I tried to describe the changes and innovations of the language in the most simple language. Thank you for your time.

Source: New Features C # 7.2 | Microsoft docs

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


All Articles