If I have these strings:
\"abc\"
= false
\"123\"
= true
\"ab2\"
I guess this answer will just be lost in between all the other ones, but anyway, here goes.
I ended up on this question via Google because I wanted to check if a string
was numeric
so that I could just use double.Parse("123")
instead of the TryParse()
method.
Why? Because it's annoying to have to declare an out
variable and check the result of TryParse()
before you know if the parse failed or not. I want to use the ternary operator
to check if the string
is numerical
and then just parse it in the first ternary expression or provide a default value in the second ternary expression.
Like this:
var doubleValue = IsNumeric(numberAsString) ? double.Parse(numberAsString) : 0;
It's just a lot cleaner than:
var doubleValue = 0;
if (double.TryParse(numberAsString, out doubleValue)) {
//whatever you want to do with doubleValue
}
I made a couple extension methods
for these cases:
public static bool IsParseableAs(this string value) {
var type = typeof(TInput);
var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
new[] { typeof(string), type.MakeByRefType() }, null);
if (tryParseMethod == null) return false;
var arguments = new[] { value, Activator.CreateInstance(type) };
return (bool) tryParseMethod.Invoke(null, arguments);
}
Example:
"123".IsParseableAs() ? double.Parse(sNumber) : 0;
Because IsParseableAs()
tries to parse the string as the appropriate type instead of just checking if the string is "numeric" it should be pretty safe. And you can even use it for non numeric types that have a TryParse()
method, like DateTime
.
The method uses reflection and you end up calling the TryParse()
method twice which, of course, isn't as efficient, but not everything has to be fully optimized, sometimes convenience is just more important.
This method can also be used to easily parse a list of numeric strings into a list of double
or some other type with a default value without having to catch any exceptions:
var sNumbers = new[] {"10", "20", "30"};
var dValues = sNumbers.Select(s => s.IsParseableAs() ? double.Parse(s) : 0);
public static TOutput ParseAs(this string value, TOutput defaultValue) {
var type = typeof(TOutput);
var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
new[] { typeof(string), type.MakeByRefType() }, null);
if (tryParseMethod == null) return defaultValue;
var arguments = new object[] { value, null };
return ((bool) tryParseMethod.Invoke(null, arguments)) ? (TOutput) arguments[1] : defaultValue;
}
This extension method lets you parse a string
as any type
that has a TryParse()
method and it also lets you specify a default value to return if the conversion fails.
This is better than using the ternary operator with the extension method above as it only does the conversion once. It still uses reflection though...
Examples:
"123".ParseAs(10);
"abc".ParseAs(25);
"123,78".ParseAs(10);
"abc".ParseAs(107.4);
"2014-10-28".ParseAs(DateTime.MinValue);
"monday".ParseAs(DateTime.MinValue);
Outputs:
123
25
123,78
107,4
28.10.2014 00:00:00
01.01.0001 00:00:00