微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否有一个标准库函数可以解析像 C# 文字语法这样的整数?

如何解决是否有一个标准库函数可以解析像 C# 文字语法这样的整数?

根据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 标准库包含多个函数,用于使用各种选项将字符串解析为整数。

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

解决方法

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

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

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

,

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

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

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

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

在那之后,我只是蛮力,使用正则表达式来解析输入字符串的部分。顺便说一下,我很确定 -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,ulong) badReturn = (false,null,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);
 }

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。