I'd like to know if there is a "safe" way to convert an object to an int
, avoiding exceptions.
I'm looking for something like public static bool TryToInt32(object value, out int result);
I know I could make something like this:
public static bool TryToInt32(object value, out int result) { try { result = Convert.ToInt32(value); return true; } catch { result = 0; return false; } }
But I'd rather avoid exceptions, because they are slowing down the process.
I think this is more elegant, but it's still "cheap":
public static bool TryToInt32(object value, out int result) { if (value == null) { result = 0; return false; } return int.TryParse(value.ToString(), out result); }
Does anyone have better ideas?
UPDATE:
This sounds a little like splitting hairs, but converting an object to string forces the implementer to create a clear ToString()
function. For example:
public class Percentage { public int Value { get; set; } public override string ToString() { return string.Format("{0}%", Value); } } Percentage p = new Percentage(); p.Value = 50; int v; if (int.TryParse(p.ToString(), out v)) { }
This goes wrong, I can do two things here, or implement the IConvertable
like this:
public static bool ToInt32(object value, out int result) { if (value == null) { result = 0; return false; } if (value is IConvertible) { result = ((IConvertible)value).ToInt32(Thread.CurrentThread.CurrentCulture); return true; } return int.TryParse(value.ToString(), out result); }
But the ToInt32
method of the IConvertible
cannot be canceled. So if it's not possible to convert the value, an exception cannot be avoided.
Or two: Is there a way to check if the object contains a implicit operator?
This is very poor:
if (value.GetType().GetMethods().FirstOrDefault(method => method.Name == "op_Implicit" && method.ReturnType == typeof(int)) != null) { result = (int)value; return true; }
TryParse() method will return false instead of throwing an exception. Thus, the TryParse() method is the safest way to converting numeric string to integer type when we don't know whether the string is a valid numeric string or not.
So, if we use the Convert. ToInt32() method, we won't have to worry about nulls.
Converts the specified string representation of a number to an equivalent 32-bit signed integer, using the specified culture-specific formatting information. Converts the string representation of a number in a specified base to an equivalent 32-bit signed integer.
int variable = 0; int.TryParse(stringValue, out variable);
If it can't be parsed, the variable will be 0. See http://msdn.microsoft.com/en-us/library/f02979c7.aspx
Spurring from the comments. The response is no. You can't do what Convert.ToInt32(object)
does without having throwed exceptions. You can do something similar (and you already did it). The only thing I would optimize is the case of value
already an int
.
if (value is int) return (int)value;
You can't do as Convert.ToInt32(object)
because Convert.ToInt32(object)
doesn't simply test if value
is short, int, long, ushort, ...
and then cast them. It checks if the value
is IConvertible
. If yes it uses the IConvertible.ToInt32
. Sadly the interface IConvertible
is quite poor: it doesn't have non-throwing methods (IConvertible.Try*
)
While stupid (but perhaps not too much), someone could make for example a UnixDateTime
struct: (UnixTime is the number of seconds from midnight 1970-01-01), where the IConvertible.ToInt32
returns this number of seconds, while the ToString()
returns a formatted date. All the int.TryParse(value.ToString(), out parsed)
would choke, while the Convert.ToInt32
would work flawlessly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With