是否有像 C# 文字语法那样解析整数的标准库函数?

Is there a standard library function that parses integers like C# literal syntax?

根据https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types

The type of an integer literal is determined by its suffix as follows:

If the literal has no suffix, its type is the first of the following types in which its value can be represented: int, uint, long, ulong.

If the literal is suffixed by U or u, its type is the first of the following types in which its value can be represented: uint, ulong.

If the literal is suffixed by L or l, its type is the first of the following types in which its value can be represented: long, ulong.

If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, its type is ulong.

.Net 标准库包含多个用于将字符串解析为具有各种选项的整数的函数。

是否有任何这样的函数可以应用上述逻辑,甚至其中的一部分,根据后缀、大小或两者返回几种整数类型之一?

一个函数只能有一个 return 类型,并且由于不同的整数类型实际上是不同的 dotnet 数据类型,因此不可能存在可以 return 其中任何一个的单一方法...除非你变得聪明 return 一个复合对象!类似于:

public class CleverReturn
{
    public Object ParsedReturnValue { get; set; }
    public string ParsedReturnValueType { get; set; }
}

'ParsedReturnValueType' 将包含该类型的完整命名空间和类型名称。您可以使用它通过反射创建正确类型的变量,并将 ParsedReturnValue 转换为它。但我知道 .NET API 中没有这样的方法。

关于您的问题(是否有解析 C# 整数文字的标准函数)- 答案是否定的。

我不确定他们如何 return 他们将被解析的值。我选择了一个相当长的元组:

(bool succeeded, Type theType, int i, uint iU, long iL, ulong iUL)

通过这种方式,您可以获得解析是否成功的指示(à la int.TryParse),以及哪种类型的解析成功的指示,以及获取值的方法(无论是什么类型)。

在那之后,我只是使用蛮力,使用 Regex 来解析输入字符串的各个部分。顺便说一句,我很确定 -234+678 都是有效的整数文字;所以我也照顾这个标志。

我从 Regex 模式和 Regex 开始:

private const string literalPattern = @"(?<prefix>[+-]?)(?<number>[0-9]+)(?<suffix>(ul|lu|u|l)?)";
private static Regex literalRegex = new Regex(literalPattern, RegexOptions.IgnoreCase);

(?<name>pattern) 模式允许命名组。你可以看到我在下面的表达式中使用它们:match.Groups["prefix"].ToString()

然后就是我的暴力解析代码:

 public static (bool, Type, int, uint, long, ulong) ParseIntegerLiteral(string theLiteral)
 {
     (bool, Type, int, uint, long, ulong) badReturn = (false, null, 0, 0, 0, 0);
     var match = literalRegex.Match(theLiteral);
     if (match.Groups.Count == 0)
     {
         return badReturn;
     }

     var negativeMult = 1;
     if (string.Equals(match.Groups["prefix"].ToString(), "-", StringComparison.OrdinalIgnoreCase))
     {
         negativeMult = -1;
     }

     Type type;
     var i = 0;
     var iu = 0U;
     var il = 0L;
     var iul = 0UL;

     switch (match.Groups["suffix"].ToString().ToUpper())
     {
         case "L": 
             type = typeof(long);
             if (!long.TryParse(match.Groups["number"].ToString(), out il))
             {
                 return badReturn;
             }
             break;
         case "U": 
             type = typeof(uint);
             if (negativeMult == -1)
             {
                 return badReturn;
             }
             if (!uint.TryParse(match.Groups["number"].ToString(), out iu))
             {
                 return badReturn;
             }

             iul = iu;

             break;
         case "UL":
         case "LU":
             type = typeof(ulong);
             if (negativeMult == -1)
             {
                 return badReturn;
             }
             if (!ulong.TryParse(match.Groups["number"].ToString(), out iul))
             {
                 return badReturn;
             }
             break;
         default:
             type = typeof(int);
             if (!int.TryParse(match.Groups["number"].ToString(), out i))
             {
                 return badReturn;
             }

             i *= negativeMult;
             il = i;
             if (i >= 0)
             {
                 iu = (uint)i;
                 iul = (ulong)i;
             }
             break;
     }

     return (true, type, i, iu, il, iul);
 }

与往常一样,代码经过了非常简单的测试。您需要为其编写一些单元测试。