.NET equivalent of size_t

As of C# v9 (which requires dotnet 5 or newer) we now have "native sized" integer types in the form of nint and nuint, which have the same basic behaviour as IntPtr and UIntPtr respectively. This makes nuint an ideal type to use when a p/invoke target requires a size_t, without the need for the extra marshalling magic linked to in Patrick McDonald's answer.


UIntPtr will work (IntPtr would probably work too, but size_t is unsigned, so UIntPtr is a better fit)

JaredPar has written something on his blog (and a follow-up) about this.


If size_t varies depending on the platform, you'll have to use IntPtr. If it is a fixed size integer, use int, uint or long (depending on the original declaration).


I've found a dirty hack that can help you achieve similar behavior. It requires that you define a compilation symbol _WIN64 for your 64-bit builds and then you can do the following:

#if _WIN64
    using size_t = UInt64;
#else
    using size_t = UInt32;
#endif

Note: you will have to use the above code in every file that wants to utilize the size_t type.

You can also define your own integer type (much like UInt64 is defined) and reuse it without having to put the above code in every file that needs access to size_t, but it's very complicated (imho).

#if _WIN64
    using _size_t = UInt64;
#else
    using _size_t = UInt32;
#endif

[Serializable]
[CLSCompliant(false)]
[ComVisible(true)]
public struct size_t : IComparable, IFormattable, IConvertible, IComparable<_size_t>, IEquatable<_size_t>
{
    private _size_t _value;

    public size_t(_size_t val)
    {
        _value = val;
    }

    // You have to add all of your overloads below
}

This will allow size_t to change it's type depending on the platform, but correctly overloading the necessary operators is very tricky!