是否有像 C# 文字语法那样解析整数的标准库函数?
Is there a standard library function that parses integers like C# literal syntax?
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);
}
与往常一样,代码经过了非常简单的测试。您需要为其编写一些单元测试。
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);
}
与往常一样,代码经过了非常简单的测试。您需要为其编写一些单元测试。