Indexing Fixed Fields Without Pinning in C# 7.3

The ability to indexing fixed fields without pinning is a new feature introduced in C# 7.3. Learn how to simplify your unsafe code.

Transcript Of The Video

Hi, I'm Andrea and welcome to Productive C#.

In this video, I want to talk about a new feature introduce in C# 7.3 that allows you to index fields without requiring pinning. 

Here, I have a solution. I want to describe what the code does and then I am going to refactor it using the new feature and show you how this can help you to write easier to understand more compact unsafe code.

If you look at the properties of our project, allow unsafe code is enabled. The reason why I am doing that is because I am using a struct that contains a fixed field inside. The fixed keyword allows to create fixed sized buffers. In this case I am creating a buffer of 10 values that contains 10 integers. You need to use unsafe in order to use this feature. It's fairly useful if you want to deal with interop with data sources from other languages or if you need to do write performant code.

Ok, we have this 10 elements array. We have a class called Calculator that create two instances of TenArray one called numbers and one called squares. The constructor of this class call the Set method 10 times to initialize the two arrays. As you can see, in the Set method we are using the fixed statement in order to pin the two values arrays in memory while we do the initialization. The reason why we do that is because when you use fixed buffers, you need to make sure that the garbage collector does not relocate the variable while you are actually accessing it. So in order to do that you use this fixed statement to pin a particular variable that you want to modify so that the garbage collector does not relocate it for the duraction of that fixed block. The fixed keyword can only be used in an unsafe context. You need to mark the method as unsafe.

In order to make changes a fixed field, up until now you have to use this fixed statmement. Basically you need to take a reference to the fixed field and save it into a pointer and then inside the fixed statement body you can use the pointer to make changes to the particular variable. 

If you look at the Get method we use the same syntax in order to access elements of the two fixed arrays. We return a tutple with the number and it's squared. Then there is a program that creates a Calculator, call the Get method for each element and printing the result. So let me run this program, before making any changes and see what the result. As you can see, it's printing the first 10 numbers and is squared.

Now, let me enable C# 7.3 and this will allows me to simplify the Set and Get methods because now I am able to index fixed fields  without doing any pinning. This means, I don't need to use the fixed statement anymore to access those fields.

I can do numbers.Values[index] = index and I can do squares.Values[index] = index * index. All of the rest is unnecessary. Now I can index directly. I don't need to use pointers any more and I don't need to use fixed statements. The code looks a lot more similar to what it would looks like if Values would be a safe array. You can do the same in Get. You don't need fixed anymore and you can return the tuple directly doing return (numbers.Values[index], squared.Values[index]).

I basically got rid of all the fixed statements, pointers and I made the code a lot more compact. Build works, run and I get the same result.  This is quite useful feature especially if you are using a lot of unsafe code and fixed buffers, game developers for example or if you need to interop a lot with other platforms. It's a very niche feature, most developers don't use unsafe code and I definitely don't recommend to use unsafe code unless you absolutely need it but if you are using it fixed buffers as fields inside structs all your code is probably full of fixed statements and pointers just to make changes to the fixed fields. This feature makes your code a lot simpler. You can go across your entire project and simplify it.

It's definitely a welcome addition to the language for those developers who need to deal with fixed buffers.

Thank you very much for watching.

Sharing is Caring
  • fishtaco says:

    Where are the code examples?

  • >