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

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

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

Возможный дубликат Как определить, является ли строка числом?

Michael Freidgeim 18.05.2017 09:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
103
1
120 074
15
Перейти к ответу Данный вопрос помечен как решенный

Ответы 15

Ответ принят как подходящий

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

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.

Обновить
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; 
}

При необходимости вы можете обернуть приведенный выше код в более полезный служебный метод, например public static bool IsInteger (string sMaybeANumber)

Gishu 13.01.2009 07:51

@Gishu: Вы правы, если все, что вас волнует, это то, может ли число конвертироваться.

NotMe 16.01.2009 18:25

Единственная проблема заключается в том, что объект Number в Javascript является числом с плавающей запятой или целым числом, поэтому изменение на double.TryParse будет более точным эквивалентом.

Chris S 09.11.2009 17:27

Вы можете быть осторожны с этим, поскольку строки «NaN» и «Infinity» анализируются до double, но многие сочтут их нечисловыми.

Mike Zboray 02.12.2012 02:22

Пример 1, первый пример, вернет истину, если задана пустая строка.

Dave Kelly 28.06.2019 14:52

Исправленный пример 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; }

stackonfire 30.10.2019 21:09

@stackonfire: ваше обновление выглядит неплохо, я включил его в пост.

NotMe 31.10.2019 17:19

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

Можно ли получить этот метод VB только в версиях .NET> 2.0?

Ed S. 13.01.2009 06:38

@ChuckD: Это субъективно. Вы ссылаетесь на внешние библиотеки, которые имеют дело с json, или пишете все для самостоятельного анализа json?

shahkalpesh 03.07.2018 17:01

@ChuckD: Избавь меня от чуши и объясни, почему это дерьмо. Для меня это просто еще одна dll, которая содержит несколько полезных классов / функций.

shahkalpesh 05.07.2018 17:06

@ChuckD Я думаю, что ты здесь неразумен. Функция выполняет свою работу, ее легко импортировать, и это не так уж и важно.

Bugs 05.07.2018 17:10

@JoelCoehoorn: Считаете ли вы, что использовать microsoft.visualbasic.dll и использовать некоторые из предоставленных в нем функций - плохая идея, независимо от того, можно ли использовать эквивалентную функцию из C# без ссылки на другую dll?

shahkalpesh 05.07.2018 17:12

Is numeric - это однострочное расширение для записи на C#. Зачем вам тащить раздутую устаревшую dll, которая, как я предполагаю, также включает в себя множество ссылок на взаимодействие с COM и дополнительные накладные расходы. Вы включаете такие вещи, как Json.Net, потому что они целенаправленны и не влекут за собой дополнительных зависимостей. Попробуйте перетащить VisualBasic.dll и перенесите свои файлы в Mono. Никто не должен учить вас этим вредным привычкам.

Chuck D 05.07.2018 17:16

@ChuckD: Вы расширяете его до Mono, вопрос не в этом. Если бы это был Mono, все было бы иначе. Как Visualbasic.dll унаследовал / раздулся? Как вызов Isnumeric включает в себя com-взаимодействие?

shahkalpesh 05.07.2018 17:20

@ChuckD: Я не знаю, почему ребята из MS пишут чушь (?) Вроде это

shahkalpesh 05.07.2018 17:26

@shahkalpesh - Здесь не место для обсуждения здравого смысла. Пожалуйста, продолжайте кодировать так, как вы считаете логичным, и я буду продолжать делать то же самое. Если вы посмотрите на направление .Net Core, вы поймете мои проблемы. Кроме того, взгляните на широко распространенный ответ и примите несколько советов, вместо того чтобы подвергать сомнению чей-то отзыв.

Chuck D 05.07.2018 17:29

@ChuckD, возможно, вы захотите начать с конструктивной критики вместо того, чтобы начинать с Импорт VisualBasic.dll для IsNumeric должен вас уволить!, что явно поможет кому-то вернуться. Ответ был еще в 2009 году и даже сейчас может быть полезен некоторым людям.

Bugs 05.07.2018 17:34

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

Chuck D 05.07.2018 18:14

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

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

}

Я предпочитаю что-то вроде этого, это позволяет вам решать, на что тестировать NumberStyle.

public static Boolean IsNumeric(String input, NumberStyles numberStyle) {
    Double temp;
    Boolean result = Double.TryParse(input, numberStyle, CultureInfo.CurrentCulture, out temp);
    return result;
}

+1 за то, что пока что был единственным человеком, использующим Double.TryParse вместо Int.TryParse :)

johnc 13.01.2009 06:43

Это тоже, очевидно, почти метод расширения.

Anthony Mastrean 24.02.2011 20:01

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

public static bool IsNumeric(string anyString)
{
    if (anyString == null)
    {
        anyString = "";
    }

    if (anyString.Length > 0)
    {
        double dummyOut = new double();
        System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-US", true);
        return Double.TryParse(anyString, System.Globalization.NumberStyles.Any, cultureInfo.NumberFormat, out dummyOut);
    }
    else
    {
        return false;
    }
}

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

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

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

public static bool IsNumeric(this String str)
{
    try
    {
        Double.Parse(str.ToString());
        return true;
    }
    catch {
    }
    return false;
}

если входной параметр - строка, зачем использовать .ToString ()?

SendETHToThisAddress 02.06.2020 02:33

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

SendETHToThisAddress 02.06.2020 09:01

Я использовал фрагмент Криса Лайвли (выбранный ответ), инкапсулированный в функции 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;
      }
   }

+1 за то, что интересно. Думаю, это скорее вопрос использования. Другими словами, если вы просто хотите убедиться, что значение можно преобразовать в число без выдачи ошибки, тогда мой исходный ответ хорош. Однако, если вас больше беспокоит, что все символы в строке на самом деле являются цифрами, необходим совершенно другой подход.

NotMe 08.06.2013 00:40
Double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out myNum)
Sam Harwell 08.06.2013 01:24

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

    /// <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;
    }

Вы по-прежнему можете использовать функцию 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));
            }
    

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

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

Abacus 31.08.2015 22:08

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

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();

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

johnnyRose 22.01.2016 00:23

Мне не нравится это решение, потому что оно вернет false для чисел с десятичной дробью. Это может быть полезно для целых чисел, но если это то, что вы хотите использовать для метода, его следует переименовать в IsInteger.

SendETHToThisAddress 02.06.2020 02:31

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

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

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

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; }
        }
    }
}

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

bool validInput = stringVariable.IsNumeric();

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

Другие вопросы по теме