Reputation: 1609
I'm working with some legacy code right now which usually used try
+ catch
in combination with Convert.ToDecimal(someString)
(for instance) to try and convert strings to decimals. For some reasons I have to use the setting that - when debugging - I stop at every thrown exception (not only user-unhandled ones) and so this got annoying and I changed it to use TryParse
methods whenever possible.
Now I'm in a situation where there's an object
value and a target Type
, and all I want to know is if I can convert the value into the target type. Right now this is done as follows:
try
{
Convert.ChangeType(val, targetType);
}
catch
{
// Do something else
}
The actual result is not important and is not used further.
While this code is working right now, as I said, it gets a bit annoying and so I wonder: Is there another way of doing the above without having to catch an exception?
I thought of something like IsAssignableFrom
on a Type
, but this doesn't seem to be applicable in my case (I don't want to assign, I want to know if explicitly converting is possible).
Upvotes: 6
Views: 1182
Reputation: 5894
Your initial guess is right.
public static bool CanChangeType(Type type)
{
return typeof (IConvertible).IsAssignableFrom(type);
}
is the right way to check by type whether Convert.ChangeType will work or not (as the exception message usually indicates). Not sure why you're opposed to this method because of the "Assign" in it's name. It's just performing some checking on the type. Other than that it doesn't actually do any assigning.
Upvotes: -1
Reputation: 3446
I'll give you a solution to "hide" exceptions. Sometimes it's neccessary to catch an exception and as you said it's annoying because the debugger will stop on every exception. I know that, but there is a way of doing that:
[DebuggerStepThrough]
public bool CanChangeType(this object instance, Type targetType)
{
try
{
Convert.ChangeType(val, targetType);
return true;
}
catch
{
return false;
}
}
The trick is the DebuggerStepThrough
-attribute.
But keep in mind that you'll never be able to debug into such a method. There is no bugfixing without removing the attribute. Knowing that a method should be short - very short and should obviously be free of all errors.
I'm having the same problems with Udp-classes that throw an exception on close. Extracting this short code to a separate method that contains no error works fine.
Upvotes: 2
Reputation: 412
If you mean casting, than you can use is
keyword like:
object someObject = GetSomeObject();
if (someObject is string)
{
..
}
But note, that casting and Convert.ChangeType
are not the same. For example, you can not cast a string to an int:
string numberString = "15";
int number = (int)numberString;
but you can use ChangeType
for it:
string numberString = "15";
int number = (int)Convert.ChangeType(numberString, typeof(int));
EDIT:
If you need to test a variable for being convertible to specific type, then why not just wrap try-catch
with Convert.ChangeType
into a test method:
public bool IsConvertibleTo<T>(object value)
{
try
{
T convertedValue = (T)Convert.ChangeType(value, typeof(T));
return true;
}
catch (InvalidCastException)
{
return false;
}
catch (FormatException)
{
return false;
}
catch (OverflowException)
{
return false;
}
}
Upvotes: 4
Reputation: 6070
If you want to check the type of val
, you should use keyword is
like this,
if (val is targetType) {
...
}
If you want to convert val
to type targetType
, you should use keyword as
like this,
targetType result = val as targetType;
if (result != null) {
...
}
Both of them won't throw an exception out!
Link: https://msdn.microsoft.com/zh-cn/library/cscsdfbt.aspx
Upvotes: 0