【问题标题】:Is there a standard library function that parses integers like C# literal syntax?是否有一个标准库函数可以解析像 C# 文字语法这样的整数?
【发布时间】:2021-06-12 03:58:59
【问题描述】:

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

整型字面量的类型由其后缀决定,如下:

如果字面量没有后缀,则它的类型是下列类型中的第一个可以表示其值:int、uint、long、ulong。

如果字面量以 U 或 u 为后缀,则它的类型是以下类型中第一个可以表示其值的类型:uint、ulong。

如果字面量以 L 或 l 为后缀,则它的类型是以下类型中第一个可以表示其值的类型:long、ulong。

如果文字以 UL、Ul、uL、ul、LU、Lu、lU 或 lu 为后缀,则其类型为 ulong。

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

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

【问题讨论】:

  • 你会如何使用这样的方法?
  • 回声亨克;我觉得我必须插话认为这种解析方法不仅会相当丑陋,使用它也可能会很混乱。我想我只是 TrimEnd U/L 并尝试将其解析为一个 long..

标签: c# .net integer


【解决方案1】:

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

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

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

这样,您将获得解析是否成功的指示(int.TryParse),以及成功解析的类型以及获取值的方法(无论是什么类型)。

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

我从正则表达式模式和正则表达式开始:

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

(?&lt;name&gt;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);
 }

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

【讨论】:

    【解决方案2】:

    一个函数只能有一个返回类型,并且由于不同的整数类型实际上是不同的 dotnet 数据类型,所以不能存在可以返回其中任何一个的单一方法......除非你变得聪明并返回一个复合类型目的!比如:

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

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

    【讨论】:

      猜你喜欢
      • 2021-03-29
      • 2021-05-13
      • 2018-01-21
      • 2012-09-08
      • 2010-12-08
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多