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;
}
Convert.ToInt32
does something different. It tries to cast the object toIConvertible
and then call the methodToInt32
. There is a subtle difference: any class could implementIConvertible
, but could have aToString()
that doesn't return a stringified number. – Shikariif (value is int) return (int)value;
– ShikariTypeCode
to determine if input is unsigned((int)typeCode - 5 & 9) == 1
(assuming you don't care about char and bool) or if it is signed((int)typeCode - 5 & 9) == 0
and useToUInt64
orToInt64
accordingly, then check bounds and profit. AllIConvertible
types implementGetTypeCode()
. Now of course if you also want to be able to do it for custom types, add your own interface to them, and check for it in the convert. – Bough