Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting to a specific type from a string value by passing the required type as parameter

I am using the following method to convert string type to a generic type

public static T Parse<T>(string value)
{
    // or ConvertFromInvariantString if you are doing serialization
    return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value);
}

I have to call it like this

Parse<Int32>(Some string value);
Parse<DateTime>(Some string value);

I am trying that instead of giving the result type explicitly, i can give it like

Parse<Type.GetType("Int32")>(Some string value);
like image 495
Vinay Pratap Singh Bhadauria Avatar asked Dec 20 '25 23:12

Vinay Pratap Singh Bhadauria


2 Answers

Generics are off the table here. Primary issue is that you are trying to take a shortcut around type identity. The name of a type is not just the type name that you use in a program. It also includes the namespace it is declared in, the display name of the assembly in which it is stored, the version number of the assembly and the public key token for the assembly's strong name. In other words, the Type.AssemblyQualifiedName.

Which requires you to write your code similar to this:

 Parse(Type.GetType("System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089""), SomeStringValue);

That will work just fine. But I'd guess that you are not going to enjoy writing that. Otherwise gives you insight in what a compiler does when it reads "Int32" in your program. It will look in its symbol table that was primed with the reference assemblies you added and notes what possible matches there may be in that table, considering what using directives are in effect.

You'd have to implement something similar in your program. The equivalent of the compiler's symbol table is a Dictionary<string, Type>. You can prime it by populating it with the kind of types that you prefer to use with a short string name. Like

  LookupTable.Add("Int32", typeof(int));
  LookupTable.Add("String", typeof(string));
  // etc...

Now you can write:

  Parse(LookupTable["Int32"], SomeStringValue);

That will work just fine. But I'd guess that you are not going to enjoy writing that. Pretty hard to beat the compiler.

like image 127
Hans Passant Avatar answered Dec 23 '25 20:12

Hans Passant


I think that if you need to specify the type at runtime instead of compile time (as in your example where you have specified "Int32" as a string) then first you need to rewrite your code with something like:

public static object Parse(Type destinationType, string value)
{
    return TypeDescriptor.GetConverter(destinationType).ConvertFromString(value);
}

Now you can call this new method writing:

var myValue = Parse(Type.GetType("System.Int32"), "33243");

Type.GetType requires you to specify the full namespace and the assembly name (Assembly qualified name), but for mscorlib types (like all primitive types) or for the currently executing assembly types you only need to specify the full namespace, like System.Int32 or System.DateTime. See MSDN.

Consider also that there are other option to convert primitive types to and from string. I suggest you to use Convert.ChangeType. This method basically check if the specified type support the IConvertible interface. Basically you can write just:

var myValue = Convert.ChangeType("23423", typeof(Int32));
or
var myValue = Convert.ChangeType("23423", Type.GetType("System.Int32"));

It also support InvariantCulture:

var myValue = Convert.ChangeType("23423", typeof(Int32), CultureInfo.InvariantCulture);

There is also a good library that combine IConvertible feature and TypeConverter, see Code Project: Universal Type Converter. This library as many useful features and it is free, also available on nuget.

like image 45
Davide Icardi Avatar answered Dec 23 '25 20:12

Davide Icardi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!