2

I am using reflection and I want to do conversion checking for exception handling.

I need to check if string can convert to unknown type in my project.

I used :

TypeConverter t = TypeDescriptor.GetConverter(typeof(string));
            Console.WriteLine(t.CanConvertTo(typeof(int)));

but it returns false !

or even this one returns false again :

StringConverter stringConverter = new StringConverter();
            Console.WriteLine(stringConverter.CanConvertTo(typeof(int)));

my quesion is that why StringConverter returns false for converting string to int ???

EDIT :

I use this code to convert string to unknown types : ( result is string )

resultCastedToTargetPropertyType = Convert.ChangeType(result,propertyInfo.PropertyType);
Parsa
  • 7,995
  • 2
  • 27
  • 37
  • 1
    Can you show us the code you would use to convert a string to an int? – mjwills Mar 28 '18 at 11:22
  • 2
    [StringConverter](https://msdn.microsoft.com/en-us/library/system.componentmodel.stringconverter(v=vs.110).aspx) This converter can only convert **to** a string. – aleha_84 Mar 28 '18 at 11:27
  • 2
    What does `TypeConverter t = TypeDescriptor.GetConverter(typeof(int)); Console.WriteLine(t.CanConvertFrom(typeof(string)));` return? – mjwills Mar 28 '18 at 11:27
  • @mjwills it returns true ! thats strange! why the opposite one returns false ?! – Parsa Mar 28 '18 at 11:30
  • 1
    Because one asks whether the string converter can convert to int. And the other asks whether the int converter can convert from string. – mjwills Mar 28 '18 at 11:31
  • @mjwills string converter logically SHOULD can convert to int ! because string can convert to int like "123" to 123 .but it seems it can not ! – Parsa Mar 28 '18 at 11:33
  • 1
    I logically should be able to lift 100kg. But alas I can not. Things aren't always the way we wish they were. _On a serious note - the docs are pretty clear - https://msdn.microsoft.com/en-us/library/system.componentmodel.stringconverter(v=vs.110).aspx#Anchor_4 ._ – mjwills Mar 28 '18 at 11:34
  • Possible duplicate of [Test if Convert.ChangeType will work between two types](https://stackoverflow.com/questions/1399273/test-if-convert-changetype-will-work-between-two-types) – mjwills Mar 28 '18 at 11:49

3 Answers3

3

Oddities of the implementation of CanConvertFrom aside, in your context you wouldn't get much help by knowing that a certain conversion could be performed until you try it. A converter cannot give you a definitive answer based on the type alone, for the same reason that there is no single answer to the question "can a string be converted to integer": the answer is "it depends on the string" - i.e. string "123" can be converted to int, while strings "hello" and "1234567891011121314151617181920" cannot be converted to int.

In other words, the answer could be obtained only when you know the value being converted. In your case it means putting try/catch block around your call of Convert.ChangeType, and interpreting each of the four exceptions it could throw (reference).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I wanted to get rid of try/catch, to make my code more clear. Also I am not going to check just int. I needed to check conversion of string to unknown types. but because in int it does not work as I expected , i mentioned int. – Parsa Mar 28 '18 at 11:43
  • 1
    @Parsa I realize that you wanted to get rid of try/catch from your question, and tried explaining why it cannot be done in general case. That is, at least until `Convert` adds `TryChangeType` or a similar non-throwing method. – Sergey Kalinichenko Mar 28 '18 at 11:47
1

A StringConverter only cares about string. What you would need is System.ComponentModel.Int32Converter. It is Int32Converter that cares about int. TypeDescriptor.GetConverter(typeof(int)) gives you that.

Essentially, a TypeConverter is usually used to format a target type to display, or to parse input back to that target type. There's nothing much involved in displaying or parsing a string to/from a string, so you will be unsurprised to hear that StringConverter does very little! Here, the interesting type is int, and Int32Converter knows how to format an int for display, and parse an int from input.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

The docs for StringConverter state:

This converter can only convert to a string. It works as a pass through for other converters that want to convert an object to a string.

Int32Converter, on the other hand, states:

This converter can only convert a 32-bit signed integer object to and from a string. The Int32 value type represents signed integers with values ranging from negative 2,147,483,648 through positive 2,147,483,647.

As such Int32Converter is likely what you want to use, rather than StringConverter.

Alternatively, consider writing a Convert.TryChangeType extension method, with a try catch block in it - this will avoid you having to worry about the individual converters. In effect you will 'try it and see'. This is especially important when doing conversions where you aren't sure whether they will work until runtime (e.g "abc" to int).

mjwills
  • 23,389
  • 6
  • 40
  • 63