Что такое эквивалент NaN или IsNumeric в C #?

Каков наиболее эффективный способ проверки входной строки, содержит ли она числовое значение (или, наоборот, не число)? Думаю, я могу использовать Double.Parse или регулярное выражение (см. Ниже), но мне было интересно, есть ли какие-то встроенные способы сделать это, например NaN() или IsNumeric() в javascript (это был VB, я не могу вспомнить?).

public static bool IsNumeric(this string value)
{
    return Regex.IsMatch(value, "^\\d+$");
}

person johnc    schedule 13.01.2009    source источник
comment
Возможный дубликат Как определить, является ли строка номер?   -  person Michael Freidgeim    schedule 18.05.2017


Ответы (14)


У этого нет накладных расходов на регулярное выражение

double myNum = 0;
String testVar = "Not A Number";

if (Double.TryParse(testVar, out myNum)) {
  // it is a number
} else {
  // it is not a number
}

Между прочим, все стандартные типы данных, за явным исключением GUID, поддерживают TryParse.

update
secretwep сообщил, что значение «2345» пройдет вышеуказанный тест в виде числа. Однако, если вам нужно убедиться, что все символы в строке являются цифрами, следует использовать другой подход.

пример 1:

public Boolean IsNumber(String s) {
  Boolean value = true;
  foreach(Char c in s.ToCharArray()) {
    value = value && Char.IsDigit(c);
  }

  return value;
}

или если вы хотите быть немного более модным

public Boolean IsNumber(String value) {
  return value.All(Char.IsDigit);
}

обновление 2 (из @stackonfire для работы с нулевыми или пустыми строками)

public Boolean IsNumber(String s) { 
    Boolean value = true; 
    if (s == String.Empty || s == null) { 
        value=false; 
    } else { 
        foreach(Char c in s.ToCharArray()) { 
            value = value && Char.IsDigit(c); 
        } 
    } return value; 
}
person NotMe    schedule 13.01.2009
comment
При необходимости вы можете обернуть приведенный выше код в более полезный служебный метод, например public static bool IsInteger (string sMaybeANumber) - person Gishu; 13.01.2009
comment
@Gishu: Вы правы, если все, что вас волнует, это то, может ли число конвертироваться. - person NotMe; 16.01.2009
comment
Единственная проблема с этим заключается в том, что объект Number в Javascript является числом с плавающей запятой или целым числом, поэтому изменение на double.TryParse будет более точным эквивалентом - person Chris S; 09.11.2009
comment
Вы можете быть осторожны с этим, поскольку строки NaN и Infinity анализируют до double, но многие сочтут их нечисловыми. - person Mike Zboray; 02.12.2012
comment
Пример 1, первый пример, вернет истину, если задана пустая строка. - person Dave Kelly; 28.06.2019
comment
Исправленный пример 1 для работы с нулевыми или пустыми строками, которые в противном случае заставляли IsNumber ошибочно возвращать истину: public Boolean IsNumber(String s) { Boolean value = true; if (s == String.Empty || s == null) { value=false; } else { foreach(Char c in s.ToCharArray()) { value = value && Char.IsDigit(c); } } return value; } - person stackonfire; 30.10.2019
comment
@stackonfire: ваше обновление выглядит неплохо, я включил его в пост. - person NotMe; 31.10.2019

Я предпочитаю что-то подобное, это позволяет вам решать, что _1 _ для проверки.

public static Boolean IsNumeric(String input, NumberStyles numberStyle) {
    Double temp;
    Boolean result = Double.TryParse(input, numberStyle, CultureInfo.CurrentCulture, out temp);
    return result;
}
person Anthony Mastrean    schedule 13.01.2009
comment
+1 за то, что был единственным человеком, использующим Double.TryParse вместо Int.TryParse :) - person johnc; 13.01.2009
comment
Это тоже, очевидно, почти метод расширения. - person Anthony Mastrean; 24.02.2011

В дополнение к предыдущим правильным ответам, вероятно, стоит указать, что «Not a Number» (NaN) в его общем использовании не эквивалентно строке, которая не может быть оценена как числовое значение. NaN обычно понимается как числовое значение, используемое для представления результата «невозможного» вычисления, когда результат не определен. В этом отношении я бы сказал, что использование Javascript немного вводит в заблуждение. В C # NaN определяется как свойство одинарных и двойных числовых типов и используется для явной ссылки на результат понижения нуля на ноль. В других языках он используется для представления других «невозможных» значений.

person Stu Mackellar    schedule 13.01.2009

Я знаю, что на это ответили по-разному, с расширениями и примерами лямбда, но комбинация обоих для простейшего решения.

public static bool IsNumeric(this String s)
{
    return s.All(Char.IsDigit);
}

или если вы используете Visual Studio 2015 (C # 6.0 или выше), тогда

public static bool IsNumeric(this String s) => s.All(Char.IsDigit);

Потрясающий C # 6 в одной строке. Конечно, это ограничено, потому что он проверяет только числовые символы.

Чтобы использовать, просто имейте строку и вызовите на ней метод, например:

bool IsaNumber = "123456".IsNumeric();
person Paul Bartlett    schedule 12.06.2015
comment
Для пользователей, незнакомых с методами расширения, может быть полезно включить некоторые дополнительная информация (или, по крайней мере, окружающий статический класс, чтобы предоставить более полный пример). - person johnnyRose; 22.01.2016
comment
Мне не нравится это решение, потому что оно вернет false для чисел с десятичной дробью. Это может быть полезно для целых чисел, но если это то, что вы хотите использовать для метода, его следует переименовать в IsInteger. - person SendETHToThisAddress; 02.06.2020

Да, IsNumeric - это VB. Обычно люди используют метод TryParse (), хотя он немного неуклюжий. Как вы предложили, вы всегда можете написать свой собственный.

int i;
if (int.TryParse(string, out i))
{

}
person Ed S.    schedule 13.01.2009

Мне нравится метод расширения, но я не люблю по возможности выбрасывать исключения. Я выбрал метод расширения, взяв здесь лучший из двух ответов.

    /// <summary>
    /// Extension method that works out if a string is numeric or not
    /// </summary>
    /// <param name="str">string that may be a number</param>
    /// <returns>true if numeric, false if not</returns>
    public static bool IsNumeric(this String str)
    {
        double myNum = 0;
        if (Double.TryParse(str, out myNum))
        {
            return true;
        }
        return false;
    }
person NER1808    schedule 30.05.2013

Вы по-прежнему можете использовать функцию Visual Basic в C #. Единственное, что вам нужно сделать, это просто следовать моим инструкциям, приведенным ниже:

  1. Добавьте ссылку в библиотеку Visual Basic, щелкнув проект правой кнопкой мыши и выбрав «Добавить ссылку»:

введите описание изображения здесь

  1. Затем импортируйте его в свой класс, как показано ниже:

    с использованием Microsoft.VisualBasic;

  2. Затем используйте его где хотите, как показано ниже:

                if (!Information.IsNumeric(softwareVersion))
            {
                throw new DataException(string.Format("[{0}] is an invalid App Version!  Only numeric values are supported at this time.", softwareVersion));
            }
    

Надеюсь, что это помогает и удачи!

person Vincy    schedule 11.07.2014
comment
Хотя я бы не рекомендовал этот метод, это правильный ответ. Не уверен, почему он был отвергнут, и, поскольку не было объяснено, почему, я проголосовал за противодействие этому :-) - person Abacus; 31.08.2015

VB имеет функцию IsNumeric. Вы можете сослаться на Microsoft.VisualBasic.dll и использовать его.

person shahkalpeshp    schedule 13.01.2009
comment
Можно ли использовать этот метод VB только в ›версиях .net 2.0? - person Ed S.; 13.01.2009
comment
@ChuckD: Это субъективно. Вы ссылаетесь на внешние библиотеки, которые имеют дело с json, или пишете все это для самостоятельного анализа json? - person shahkalpeshp; 03.07.2018
comment
@ChuckD: Избавь меня от чуши и объясни, почему это чушь. Для меня это просто еще одна dll, которая содержит несколько полезных классов / функций. - person shahkalpeshp; 05.07.2018
comment
@ChuckD Я думаю, что ты здесь неразумен. Функция выполняет свою работу, ее легко импортировать, и это не так уж и важно. - person Bugs; 05.07.2018
comment
@JoelCoehoorn: Считаете ли вы, что использовать microsoft.visualbasic.dll и использовать некоторые из предоставленных в нем функций - плохая идея, независимо от того, можно ли использовать эквивалентную функцию из C # без ссылки на другую dll? - person shahkalpeshp; 05.07.2018
comment
Is numeric - это однострочное расширение для записи на C #. Зачем вам тащить раздутую устаревшую dll, которая, как я предполагаю, также включает в себя множество ссылок на взаимодействие с COM и дополнительные накладные расходы. Вы включаете такие вещи, как Json.Net, потому что они целенаправленны и не влекут за собой дополнительных зависимостей. Попробуйте перетащить VisualBasic.dll и перенесите свои файлы в Mono. Никто не должен учить вас этим вредным привычкам. - person Chuck D; 05.07.2018
comment
@ChuckD: Вы расширяете его до Mono, вопрос не в этом. Если бы это был Mono, все было бы иначе. Как у Visualbasic.dll устаревший / раздутый? Как вызов Isnumeric включает в себя com-взаимодействие? - person shahkalpeshp; 05.07.2018
comment
@ChuckD: Я не знаю, почему люди из MS пишут чушь (?) Вроде это - person shahkalpeshp; 05.07.2018
comment
@shahkalpesh - Здесь не место для обсуждения здравого смысла. Пожалуйста, продолжайте кодировать так, как вы считаете логичным, и я буду продолжать делать то же самое. Если вы посмотрите на направление .Net Core, вы поймете мои проблемы. Кроме того, взгляните на широко распространенный ответ и примите несколько советов, вместо того чтобы подвергать сомнению чей-то отзыв. - person Chuck D; 05.07.2018
comment
@ChuckD, возможно, вы захотите начать с конструктивной критики вместо того, чтобы начинать с Импорт VisualBasic.dll для IsNumeric должен вас уволить!, что явно поможет кому-то поддержать. Ответ был дан еще в 2009 году и даже сейчас может быть полезен некоторым людям. - person Bugs; 05.07.2018
comment
Мои извинения, комментарии были убраны. Если вы решили аргументировать свой предложенный ответ вместо принятого, значит, вы неправильно используете сайт. - person Chuck D; 05.07.2018

Простое расширение:

public static bool IsNumeric(this String str)
{
    try
    {
        Double.Parse(str.ToString());
        return true;
    }
    catch {
    }
    return false;
}
person MrSiir    schedule 01.12.2012
comment
если входной параметр - строка, зачем использовать .ToString ()? - person SendETHToThisAddress; 02.06.2020
comment
Этот ответ хорош, потому что он устраняет ненужную переменную, необходимую для метода TryParse, который используется в ответах, таких как решение NER1808. - person SendETHToThisAddress; 02.06.2020

Возможно, это функция C # 3, но вы могли бы использовать double.NaN.

person kenny    schedule 16.05.2010

Фактически, Double.NaN поддерживается во всех версиях .NET 2.0 и выше.

person Madcat    schedule 24.11.2010

Я использовал фрагмент Криса Лайвли (выбранный ответ), инкапсулированный в функции bool, такой как предложение Гишу, в течение года или двух. Я использовал его, чтобы убедиться, что определенные строки запроса были только числовыми, прежде чем продолжить дальнейшую обработку. Я начал получать некоторые ошибочные строки запроса, которые отмеченный ответ не обрабатывал, в частности, всякий раз, когда после числа, такого как «3645», ставилась запятая (возвращено истина). Это получившийся мод:

   static public bool IsNumeric(string s)
   {
      double myNum = 0;
      if (Double.TryParse(s, out myNum))
      {
         if (s.Contains(",")) return false;
         return true;
      }
      else
      {
         return false;
      }
   }
person secretwep    schedule 03.04.2013
comment
+1 за то, что интересно. Думаю, это скорее вопрос использования. Другими словами, если вы просто хотите убедиться, что значение можно преобразовать в число без выдачи ошибки, тогда мой исходный ответ хорош. Однако, если вас больше беспокоит, что все символы в строке на самом деле являются цифрами, необходим совершенно другой подход. - person NotMe; 08.06.2013

У меня немного другая версия, которая возвращает число. Я предполагаю, что в большинстве случаев после тестирования строки вы захотите использовать номер.

public bool IsNumeric(string numericString, out Double numericValue)
{
    if (Double.TryParse(numericString, out numericValue))
        return true;
    else
        return false;
}
person Keith Aymar    schedule 07.03.2018

Это модифицированная версия решения, предложенного г-ном Сииром. Я считаю, что добавление метода расширения - лучшее решение для повторного использования и простоты вызывающего метода.

public static bool IsNumeric(this String s)
{
    try { double.Parse(s); return true; }
    catch (Exception) { return false; }
}

Я изменил тело метода, чтобы он умещался в 2 строки, и удалил ненужную реализацию .ToString (). Для тех, кто не знаком с методами расширения, вот как реализовать:

Создайте файл класса с именем ExtensionMethods. Вставьте этот код:

using System;
using System.Collections.Generic;
using System.Text;

namespace YourNameSpaceHere
{
    public static class ExtensionMethods
    {
        public static bool IsNumeric(this String s)
        {
            try { double.Parse(s); return true; }
            catch (Exception) { return false; }
        }
    }
}

Замените YourNameSpaceHere своим фактическим NameSpace. Сохранить изменения. Теперь вы можете использовать метод расширения в любом месте вашего приложения:

bool validInput = stringVariable.IsNumeric();

Примечание: этот метод вернет истину для целых и десятичных чисел, но вернет ложь, если строка содержит запятую. Если вы хотите принимать ввод с запятыми или символами, такими как «$», я бы предложил реализовать метод для удаления этих символов сначала, а затем проверить, является ли IsNumeric.

person SendETHToThisAddress    schedule 02.06.2020