Skip to content

System.IntPtr and System.UIntPtr Improvements #21943

@tannergooding

Description

@tannergooding

Rationale

The .NET framework provides the System.IntPtr and System.UIntPtr types which wrap the native int IL primitive (as per ECMA-335).

These types are frequently used to represent both handles/pointers and integers whose size depend on the underlying platform.

When being used to represent the latter (platform sized integer) type, users may find a difficult time performing some basic operations, such as comparing two native ints to determine sort order.

Additionally, with the proposed C# Native Sized Number Types (dotnet/csharplang#435) where language support for the primitive operations will be exposed (currently this will be done via partial erasure), the use of System.IntPtr and System.UIntPtr as native int types will become more prevalent (F# is one language that already exposes these operators).

As such, these types should be modified to expose a set of APIs that make other common operations easier to perform.

Proposed API

The proposed API here only shows the members that would be new to the types.

System.IntPtr

[StructLayout(LayoutKind.Sequential)] // This is implicitly set by the compiler, but should be explicitly declared, as it is done for System.Int32
public struct IntPtr : IComparable, IComparable<IntPtr>, IFormattable
{
    public static IntPtr MaxValue { get; }
    public static IntPtr MinValue { get; }

    public static int ShiftMask { get; } // Runtime constant equivalent to (sizeof(nint) * 8) - 1

    int IComparable.CompareTo(object value);    // Explicitly implemented to ensure that users still get compile-time type checking
    public int CompareTo(IntPtr value);

    public bool Equals(IntPtr other);           // This is currently explicitly implemented as IEquatable<IntPtr>.Equals(IntPtr other)

    public string ToString(IFormatProvider provider);
    public string ToString(string format, IFormatProvider provider);

    public static IntPtr Parse(string s);
    public static IntPtr Parse(string s, NumberStyles style);
    public static IntPtr Parse(string s, IFormatProvider provider);
    public static IntPtr Parse(string s, NumberStyles style, IFormatProvider provider);

    public static bool TryParse(string s, out IntPtr result);
    public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out IntPtr result);
}

System.UIntPtr

public struct UIntPtr : IComparable, IComparable<UIntPtr>, IFormattable
{
    public static UIntPtr MaxValue { get; }
    public static UIntPtr MinValue { get; }

    public static int ShiftMask { get; } // Runtime constant equivalent to (sizeof(nint) * 8) - 1

    int IComparable.CompareTo(object value);    // Explicitly implemented to ensure that users still get compile-time type checking
    public int CompareTo(UIntPtr value);

    public bool Equals(UIntPtr other);          // This is currently explicitly implemented as IEquatable<UIntPtr>.Equals(UIntPtr other)

    public string ToString(string format);      // This is currently exposed on System.IntPtr, but not on System.UIntPtr
    public string ToString(IFormatProvider provider);
    public string ToString(string format, IFormatProvider provider);

    public static UIntPtr Parse(string s);
    public static UIntPtr Parse(string s, NumberStyles style);
    public static UIntPtr Parse(string s, IFormatProvider provider);
    public static UIntPtr Parse(string s, NumberStyles style, IFormatProvider provider);

    public static bool TryParse(string s, out UIntPtr result);
    public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out UIntPtr result);
}

Other Thoughts

Implementing System.IConvertible is done by the other primitive types and may be useful in some cases here as well.

It might be worthwhile having int implement IComparable<IntPtr> and IEquatable<IntPtr>, given that these are valid operations as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-approvedAPI was approved in API review, it can be implementedarea-System.Runtimebreaking-changeIssue or PR that represents a breaking API or functional change over a previous release.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions