A more elegant way to find out if I can convert a value to a specific type

I am working with some legacy code right now that used try + catch in conjunction with Convert.ToDecimal(someString) (for example) to try to convert strings to decimal numbers. For some reason, I have to use a parameter that - when debugging - stops with every exception (not just custom unhandled ones), and therefore it is annoying, and I changed it to use TryParse methods TryParse possible.

Now I am in a situation where there is an object value and a Type target, and all I want to know is if I can convert the value to the target type. Now this is done as follows:

 try { Convert.ChangeType(val, targetType); } catch { // Do something else } 

The actual result is not important and is no longer used.

While this code is working right now, as I said, it is a little annoying, and so I wonder: Is there any other way to do this without catching the exception?

I thought of something like IsAssignableFrom in Type , but that doesn't seem to apply in my case (I don't want to assign, I want to know if explicit conversion is possible).

+6
source share
4 answers

If you mean casting, you can use the is keyword, for example:

 object someObject = GetSomeObject(); if (someObject is string) { .. } 

But note that casting and Convert.ChangeType do not match. For example, you cannot pass a string to 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 to convert to a specific type, then why not just wrap try-catch with Convert.ChangeType in 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; } } 
+3
source

I will give you the decision to "hide" exceptions. Sometimes it is necessary to catch an exception, and, as you said, it is annoying because the debugger will stop at each exception. I know this, but there is a way to do this:

 [DebuggerStepThrough] public bool CanChangeType(this object instance, Type targetType) { try { Convert.ChangeType(val, targetType); return true; } catch { return false; } } 

Trick DebuggerStepThrough -attribute.

But keep in mind that you can never debug such a method. Fixed not removing attribute. Knowing that the method should be short - very short and, obviously, should be free from all errors.

I have the same problems with Udp classes that throw an exception on close. Extracting this short code into a separate method that does not contain an error works fine.

+2
source

If you want to check the type of val , you should use the is keyword like this,

 if (val is targetType) { ... } 

If you want to convert val to targetType type, you should use the as keyword like this,

 targetType result = val as targetType; if (result != null) { ... } 

Both of them will not throw an exception!

Link: https://msdn.microsoft.com/zh-cn/library/cscsdfbt.aspx

0
source

Your initial assumption is correct.

  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). You don’t know why you are against this method because of the β€œAssign” name in it. It just does some type checking. In addition, this is not actually done.

0
source

All Articles