На самом деле я хотел добавить это как комментарий, но не мог украсить его легко, поэтому добавлял как ответ, пожалуйста, не рассматривайте это как ответ.
Это то, что я сделал, чтобы понять -
выполнять следующие один за другим и понимать вывод на каждом шаге
a = [1,2]
b = [1,2,3]
b.pop()
id(a)
id(b)
a is b
a == b
You will simply need to do a type check for each of the basic numeric types.
Here's an extension method that should do the job:
public static bool IsNumber(this object value)
{
return value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is int
|| value is uint
|| value is long
|| value is ulong
|| value is float
|| value is double
|| value is decimal;
}
This should cover all numeric types.
It seems you do actually want to parse the number from a string during deserialisation. In this case, it would probably just be best to use double.TryParse
.
string value = "123.3";
double num;
if (!double.TryParse(value, out num))
throw new InvalidOperationException("Value is not a number.");
Of course, this wouldn't handle very large integers/long decimals, but if that is the case you just need to add additional calls to long.TryParse
/ decimal.TryParse
/ whatever else.
Taken from Scott Hanselman's Blog:
public static bool IsNumeric(object expression)
{
if (expression == null)
return false;
double number;
return Double.TryParse( Convert.ToString( expression
, CultureInfo.InvariantCulture)
, System.Globalization.NumberStyles.Any
, NumberFormatInfo.InvariantInfo
, out number);
}
Воспользуйтесь преимуществом свойства IsPrimitive, чтобы создать удобный метод расширения:
public static bool IsNumber(this object obj)
{
if (Equals(obj, null))
{
return false;
}
Type objType = obj.GetType();
objType = Nullable.GetUnderlyingType(objType) ?? objType;
if (objType.IsPrimitive)
{
return objType != typeof(bool) &&
objType != typeof(char) &&
objType != typeof(IntPtr) &&
objType != typeof(UIntPtr);
}
return objType == typeof(decimal);
}
РЕДАКТИРОВАТЬ: Исправлено согласно комментариям. Дженерики были удалены, поскольку типы значений .GetType (). Также включено исправление для значений, допускающих значение NULL.
Здесь есть три различных понятия:
равно
- например, if (obj is int) {...}
TryParse ()
ToString ()
может дать что-то, что выглядит как число, затем вызовите ToString ()
и обработайте его как строку В обоих первых двух случаях вам, вероятно, придется обрабатывать отдельно каждый числовой тип, который вы хотите поддерживать ( double
/ decimal
/ int
) - например, каждый из них имеет разные диапазоны и точность.
Assuming your input is a string...
There are 2 ways:
use Double.TryParse()
double temp;
bool isNumber = Double.TryParse(input, out temp);
use Regex
bool isNumber = Regex.IsMatch(input,@"-?\d+(\.\d+)?");
You could use code like this:
if (n is IConvertible)
return ((IConvertible) n).ToDouble(CultureInfo.CurrentCulture);
else
// Cannot be converted.
If your object is an Int32
, Single
, Double
etc. it will perform the conversion. Also, a string implements IConvertible
but if the string isn't convertible to a double then a FormatException
will be thrown.
Yes, this works:
object x = 1;
Assert.That(x is int);
For a floating point number you would have to test using the float type:
object x = 1f;
Assert.That(x is float);
Если ваше требование действительно
.ToString () приведет к строке содержащие цифры и +, - ,.
, и вы хотите использовать double.TryParse, тогда вам нужно использовать перегрузку, которая принимает параметр NumberStyles, и убедитесь, что вы используете инвариантный язык и региональные параметры.
Например, для числа, которое может иметь начальный знак, без начальных или конечных пробелов, без разделителя тысяч и десятичного разделителя с точкой, используйте:
NumberStyles style =
NumberStyles.AllowLeadingSign |
NumberStyles.AllowDecimalPoint |
double.TryParse(input, style, CultureInfo.InvariantCulture, out result);