dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.38k stars 4.75k forks source link

[API Proposal]: System.Convert base on ReadOnlySpan<char> #107276

Open universorum opened 2 months ago

universorum commented 2 months ago

Background and motivation

Consider the string Value: 0xff. If the API only accept the string, we will need create the new string instance by str[^2..].

In the API inside, many method like ParseNumbers.StringToInt (internal class) and int.Parse already accpet the ReadOnlySpan<char> type. Why we cannot pass the ReadOnlySpan<char> to API to avoid alloc?

also #22848

API Proposal

namespace System;

public static class Convert
{
    public static byte   ToByte(ReadOnlySpan<char>? value);
    public static byte   ToByte(ReadOnlySpan<char>? value, IFormatProvider? provider);
    public static byte   ToByte(ReadOnlySpan<char>? value, int fromBase);
    public static sbyte  ToSByte(ReadOnlySpan<char>? value);
    public static sbyte  ToSByte(ReadOnlySpan<char>? value, IFormatProvider? provider);
    public static sbyte  ToSByte(ReadOnlySpan<char>? value, int fromBase);
    public static short  ToInt16(ReadOnlySpan<char>? value);
    public static short  ToInt16(ReadOnlySpan<char>? value, IFormatProvider? provider);
    public static short  ToInt16(ReadOnlySpan<char>? value, int fromBase);
    public static ushort ToUInt16(ReadOnlySpan<char>? value);
    public static ushort ToUInt16(ReadOnlySpan<char>? value, int fromBase);
    public static ushort ToUInt16(ReadOnlySpan<char>? value, IFormatProvider? provider);
    public static int    ToInt32(ReadOnlySpan<char>? value);
    public static int    ToInt32(ReadOnlySpan<char>? value, int fromBase);
    public static int    ToInt32(ReadOnlySpan<char>? value, IFormatProvider? provider);
    public static uint   ToUInt32(ReadOnlySpan<char>? value);
    public static uint   ToUInt32(ReadOnlySpan<char>? value, int fromBase);
    public static uint   ToUInt32(ReadOnlySpan<char>? value, IFormatProvider? provider);
    public static long   ToInt64(ReadOnlySpan<char>? value);
    public static long   ToInt64(ReadOnlySpan<char>? value, int fromBase);
    public static long   ToInt64(ReadOnlySpan<char>? value, IFormatProvider? provider);
    public static ulong  ToUInt64(ReadOnlySpan<char>? value);
    public static ulong  ToUInt64(ReadOnlySpan<char>? value, IFormatProvider? provider);
    public static ulong  ToUInt64(ReadOnlySpan<char>? value, int fromBase);
}

API Usage

var str = "Value: 0xff"
long result = Convert.ToInt64(str.AsSpan()[^2..], 16);

Alternative Designs

No response

Risks

No response

dotnet-policy-service[bot] commented 2 months ago

Tagging subscribers to this area: @dotnet/area-system-numerics See info in area-owners.md if you want to be subscribed.

huoyaoyuan commented 2 months ago

The Convert pattern is deprecated for a long time. But we do need a better way to convert with different bases.

AmrAlSayed0 commented 2 months ago

@huoyaoyuan Out of curiosity, deprecated in favor of what?

huoyaoyuan commented 2 months ago

deprecated in favor of what?

Parse methods on each type, like int.Parse and int.TryParse.

tannergooding commented 2 months ago

But we do need a better way to convert with different bases.

This largely already exists. Convert only supports a fixed set of bases today: 2, 8, 10, and 16

All of these except octal (8) are supported via passing in the relevant NumberStyles options to the int.Parse and related APIs nowadays

huoyaoyuan commented 2 months ago

All of these except octal (8) are supported via passing in the relevant NumberStyles options to the int.Parse and related APIs nowadays

Yes, but it's still gap we can improve: add octal options to NumberStyles, and dispatch NumberStyles based on numeric base values.

stephentoub commented 2 months ago

and dispatch NumberStyles based on numeric base values

I don't think I've ever seen a meaningful example where fromBase wasn't a constant. What's the scenario for this?

colejohnson66 commented 2 months ago

Duplicate of #61397?