Я искал int.TryParse
реализацию метода, как он работает на самом деле, но не нашел. Я должен знать, string
числовое ли это значение, но сейчас я не хочу его преобразовывать.
Так что мне нужен только bool
результат int.TryParse
. Итак, вопросы:
- Есть ли функция, которая может дать только
bool
результат,
и
- Я хотел бы знать, как на
int.TryParse
самом деле работает (есть лиtry ... catch
внутри или перебирает символы вводаstring
)?
Convert.ToInt32()
, но это вызовет исключение, если строка не может быть проанализирована. 2. Ему придется перебирать строку, но, вероятно, он не поймает никаких исключений, так как это быстрее, чемConvert.ToInt32()
Ответы:
Если вам нужен только
bool
результат, просто используйте возвращаемое значение и игнорируйтеout
параметр.bool successfullyParsed = int.TryParse(str, out ignoreMe); if (successfullyParsed){ // ... }
Изменить : Между тем вы также можете посмотреть исходный исходный код :
System.Int32.TryParse
Если я хочу знать, как что-то на самом деле реализовано, я использую
ILSpy
для декомпиляции .NET-кода.Вот результат:
// int /// <summary>Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the operation succeeded.</summary> /// <returns>true if s was converted successfully; otherwise, false.</returns> /// <param name="s">A string containing a number to convert. </param> /// <param name="result">When this method returns, contains the 32-bit signed integer value equivalent to the number contained in s, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the s parameter is null, is not of the correct format, or represents a number less than <see cref="F:System.Int32.MinValue"></see> or greater than <see cref="F:System.Int32.MaxValue"></see>. This parameter is passed uninitialized. </param> /// <filterpriority>1</filterpriority> public static bool TryParse(string s, out int result) { return Number.TryParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result); } // System.Number internal unsafe static bool TryParseInt32(string s, NumberStyles style, NumberFormatInfo info, out int result) { byte* stackBuffer = stackalloc byte[1 * 114 / 1]; Number.NumberBuffer numberBuffer = new Number.NumberBuffer(stackBuffer); result = 0; if (!Number.TryStringToNumber(s, style, ref numberBuffer, info, false)) { return false; } if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None) { if (!Number.HexNumberToInt32(ref numberBuffer, ref result)) { return false; } } else { if (!Number.NumberToInt32(ref numberBuffer, ref result)) { return false; } } return true; }
И нет,
Try-Catchs
на дороге ничего не вижу :// System.Number private unsafe static bool TryStringToNumber(string str, NumberStyles options, ref Number.NumberBuffer number, NumberFormatInfo numfmt, bool parseDecimal) { if (str == null) { return false; } fixed (char* ptr = str) { char* ptr2 = ptr; if (!Number.ParseNumber(ref ptr2, options, ref number, numfmt, parseDecimal) || ((ptr2 - ptr / 2) / 2 < str.Length && !Number.TrailingZeros(str, (ptr2 - ptr / 2) / 2))) { return false; } } return true; } // System.Number private unsafe static bool ParseNumber(ref char* str, NumberStyles options, ref Number.NumberBuffer number, NumberFormatInfo numfmt, bool parseDecimal) { number.scale = 0; number.sign = false; string text = null; string text2 = null; string str2 = null; string str3 = null; bool flag = false; string str4; string str5; if ((options & NumberStyles.AllowCurrencySymbol) != NumberStyles.None) { text = numfmt.CurrencySymbol; if (numfmt.ansiCurrencySymbol != null) { text2 = numfmt.ansiCurrencySymbol; } str2 = numfmt.NumberDecimalSeparator; str3 = numfmt.NumberGroupSeparator; str4 = numfmt.CurrencyDecimalSeparator; str5 = numfmt.CurrencyGroupSeparator; flag = true; } else { str4 = numfmt.NumberDecimalSeparator; str5 = numfmt.NumberGroupSeparator; } int num = 0; char* ptr = str; char c = *ptr; while (true) { if (!Number.IsWhite(c) || (options & NumberStyles.AllowLeadingWhite) == NumberStyles.None || ((num & 1) != 0 && ((num & 1) == 0 || ((num & 32) == 0 && numfmt.numberNegativePattern != 2)))) { bool flag2; char* ptr2; if ((flag2 = ((options & NumberStyles.AllowLeadingSign) != NumberStyles.None && (num & 1) == 0)) && (ptr2 = Number.MatchChars(ptr, numfmt.positiveSign)) != null) { num |= 1; ptr = ptr2 - (IntPtr)2 / 2; } else { if (flag2 && (ptr2 = Number.MatchChars(ptr, numfmt.negativeSign)) != null) { num |= 1; number.sign = true; ptr = ptr2 - (IntPtr)2 / 2; } else { if (c == '(' && (options & NumberStyles.AllowParentheses) != NumberStyles.None && (num & 1) == 0) { num |= 3; number.sign = true; } else { if ((text == null || (ptr2 = Number.MatchChars(ptr, text)) == null) && (text2 == null || (ptr2 = Number.MatchChars(ptr, text2)) == null)) { break; } num |= 32; text = null; text2 = null; ptr = ptr2 - (IntPtr)2 / 2; } } } } c = *(ptr += (IntPtr)2 / 2); } int num2 = 0; int num3 = 0; while (true) { if ((c >= '0' && c <= '9') || ((options & NumberStyles.AllowHexSpecifier) != NumberStyles.None && ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))) { num |= 4; if (c != '0' || (num & 8) != 0) { if (num2 < 50) { number.digits[(IntPtr)(num2++)] = c; if (c != '0' || parseDecimal) { num3 = num2; } } if ((num & 16) == 0) { number.scale++; } num |= 8; } else { if ((num & 16) != 0) { number.scale--; } } } else { char* ptr2; if ((options & NumberStyles.AllowDecimalPoint) != NumberStyles.None && (num & 16) == 0 && ((ptr2 = Number.MatchChars(ptr, str4)) != null || (flag && (num & 32) == 0 && (ptr2 = Number.MatchChars(ptr, str2)) != null))) { num |= 16; ptr = ptr2 - (IntPtr)2 / 2; } else { if ((options & NumberStyles.AllowThousands) == NumberStyles.None || (num & 4) == 0 || (num & 16) != 0 || ((ptr2 = Number.MatchChars(ptr, str5)) == null && (!flag || (num & 32) != 0 || (ptr2 = Number.MatchChars(ptr, str3)) == null))) { break; } ptr = ptr2 - (IntPtr)2 / 2; } } c = *(ptr += (IntPtr)2 / 2); } bool flag3 = false; number.precision = num3; number.digits[(IntPtr)num3] = '\0'; if ((num & 4) != 0) { if ((c == 'E' || c == 'e') && (options & NumberStyles.AllowExponent) != NumberStyles.None) { char* ptr3 = ptr; c = *(ptr += (IntPtr)2 / 2); char* ptr2; if ((ptr2 = Number.MatchChars(ptr, numfmt.positiveSign)) != null) { c = *(ptr = ptr2); } else { if ((ptr2 = Number.MatchChars(ptr, numfmt.negativeSign)) != null) { c = *(ptr = ptr2); flag3 = true; } } if (c >= '0' && c <= '9') { int num4 = 0; do { num4 = num4 * 10 + (int)(c - '0'); c = *(ptr += (IntPtr)2 / 2); if (num4 > 1000) { num4 = 9999; while (c >= '0' && c <= '9') { c = *(ptr += (IntPtr)2 / 2); } } } while (c >= '0' && c <= '9'); if (flag3) { num4 = -num4; } number.scale += num4; } else { ptr = ptr3; c = *ptr; } } while (true) { if (!Number.IsWhite(c) || (options & NumberStyles.AllowTrailingWhite) == NumberStyles.None) { bool flag2; char* ptr2; if ((flag2 = ((options & NumberStyles.AllowTrailingSign) != NumberStyles.None && (num & 1) == 0)) && (ptr2 = Number.MatchChars(ptr, numfmt.positiveSign)) != null) { num |= 1; ptr = ptr2 - (IntPtr)2 / 2; } else { if (flag2 && (ptr2 = Number.MatchChars(ptr, numfmt.negativeSign)) != null) { num |= 1; number.sign = true; ptr = ptr2 - (IntPtr)2 / 2; } else { if (c == ')' && (num & 2) != 0) { num &= -3; } else { if ((text == null || (ptr2 = Number.MatchChars(ptr, text)) == null) && (text2 == null || (ptr2 = Number.MatchChars(ptr, text2)) == null)) { break; } text = null; text2 = null; ptr = ptr2 - (IntPtr)2 / 2; } } } } c = *(ptr += (IntPtr)2 / 2); } if ((num & 2) == 0) { if ((num & 8) == 0) { if (!parseDecimal) { number.scale = 0; } if ((num & 16) == 0) { number.sign = false; } } str = ptr; return true; } } str = ptr; return false; }
источник
Просто потому, что
int.TryParse
дает вам ценность, не означает, что вам нужно ее сохранить; вы вполне можете сделать это:int temp; if (int.TryParse(inputString, out temp)) { // do stuff }
Вы можете
temp
полностью игнорировать, если вам это не нужно. Если он вам действительно нужен, то он ждет вас, когда вы этого захотите.Что касается внутреннего устройства, насколько я помню, он пытается прочитать необработанные байты строки как int и проверяет, верен ли результат или что-то в этом роде; это не так просто, как итерация путем поиска нечисловых символов.
источник
Теперь в C # 7.0 и выше мы можем написать следующее:
if (int.TryParse(inputString, out _)) { //do stuff }
источник
int someInt
передается вint.TryParse
likeint.TryParse(out someInt)
,int.TryParse
может помещать ее выводsomeInt
, даже если обычно он находится вне области видимости.TryParse - лучший способ синтаксического анализа или проверки в одной строке:
int nNumber = int.TryParse("InputString", out nNumber) ? nNumber : 1;
Краткое описание:
источник
cannot use local variable 'nCurPage' before it is declared
Regex скомпилирован, поэтому для ускорения создайте его один раз и используйте повторно.
Новое занимает больше времени, чем IsMatch.
Это проверяет только все цифры.
Он не проверяет диапазон.
Если вам нужно проверить диапазон, попробуйте TryParse.
private static Regex regexInt = new Regex("^\\d+$"); static bool CheckReg(string value) { return regexInt.IsMatch(value); }
источник
Проверьте эту простую программу, чтобы понять
int.TryParse
class Program { static void Main() { string str = "7788"; int num1; bool n = int.TryParse(str, out num1); Console.WriteLine(num1); Console.ReadLine(); } }
Выход: 7788
источник