5

Introducing C# 9: Native-sized integers

 3 years ago
source link: https://anthonygiretti.com/2020/08/19/introducing-c-9-native-sized-integers/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Introducing C# 9: Native-sized integers

2020-08-19 by anthonygiretti

Introduction

What are native-sized integers ? They are designed to be an integer which size is specific to the platform. In other words, an instance of this type must be 32 bits on 32-bit hardwares / operating systems, 64 bits on 64-bit hardwares / operating systems.

The CLR / JIT / MSIL supports the definition and usage of native integers / unsigned integers. Since .NET 4.0’s CLR, it is possible to add / substract an integer from a System.IntPtr / System.UIntPtr, and it is possible to do == / != comparisons with other System.IntPtr / System.UIntPtr, but any other comparison operation is prohibited…, i.e. they cannot be compared with >>= etc. to each other, so System.IntPtr / System.UIntPtr remain very basic in the amount of pointer arithmetic.

C# 9 brings what mono has brought before: language support for a native-sized signed and unsigned integer types with nint and nuint keyword. The motivation here is for interop scenarios and for low-level libraries, so might not use them often.

Types nint and nuint are represented by the underlying types System.IntPtr and System.UIntPtr with compiler surfacing additional conversions and operations for those types as native ints.

Sources: Microsoft and Github

C# 9 syntax, constants and usage

nint constants are in the range [ int.MinValueint.MaxValue ].

nuint constants are in the range [ uint.MinValueuint.MaxValue ].

There are no MinValue or MaxValue o nint or nuint because, other than nuint.MinValue, those values cannot be emitted as constants.

Usage samples:

public class Program { public static void Main(string[] args) { nint x = 3; int y = 3; long v = 10;

nint.Equals(x, y); // False nint.Equals(x, (nint)y); // True

var test1 = y + 1 > x; // True; var test2 = y - 1 == x; // False

var test3 = typeof(nint); // System.IntPtr var test4 = typeof(nuint); // System.UIntPtr var test5 = (x + 1).GetType(); // System.IntPtr var test6 = (x + y).GetType(); // System.IntPtr var test7 = (x + v).GetType(); // System.Int64

dynamic z = 1; var test8 = z + x; // RuntimeBinderException: '+' cannot be applied 'System.IntPtr' and 'System.IntPtr' } }

When you add an int to a nint the result is a nint, but if you add a long to an nint the result will be a long. This is because the native depending on the platform could be a 32-bit integer or a 64-bits integer.

You can notice that arrays support native-sized signed type as index, but not lists, example:

public class CountryService { public Country GetByIndex(Country[] countries, nint index) { return countries[index]; // legal }

public Country GetByIndex(List<Country> countries, nint index) { return countries[index]; // CS1503: cannot convert from 'nint' to int } }

public class Country { public string Name { get; set; } }

Microsoft docs says enum support nint and nuint as base type: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/native-integers#miscellaneous

Unfortunately I’m not able to test it, I have a compiler error for now with the latest release of Roslyn I’am currently using (3.8.0-1.20330.5)

A soon as an update is available for enum and native-integers, I’ll update this post.

Thanks for reading 🙂

Like this:

Loading...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK