简体   繁体   中英

Assigning type at runtime

I have a variable x of type T and value that is in a string. For example I have:

bool x, value = "True"
int x, value = "1"
  • Is there a generic way to assign/parse/deserialize the value to x?

Note that T may be referenced or primitive type!

you can use Convert.ChangeType method .

This will cover all base types conversion.

Example : var i = Convert.ChangeType("1", typeof(int));

You can also take a look at the IConvertible interface that you can use for converting your own objects from or to another type.

Finally, as codymanix said, you can rely on the OOB XmlSerialization or Binary Serialization to serialize your objects.

[edit] you can check at compile time if the target type is convertible by wrapping the convert.ChangeType method in an utility class like this :

public static class ConvertUtility
{
    public static T Convert<T>(object source) where T : IConvertible
    {
        return (T)System.Convert.ChangeType(source, typeof(T));
    }              
}

I wrote this reflection based approach some time ago. It's relatively untested though. It looks for methods called Parse and TryParse . And I didn't take care of locale (in)dependent parsing either.

    private static class ParseDelegateStore<T>
    {
        public static ParseDelegate<T> Parse;
        public static TryParseDelegate<T> TryParse;
    }

    private delegate T ParseDelegate<T>(string s);
    private delegate bool TryParseDelegate<T>(string s, out T result);


    public static T Parse<T>(string s)
    {
        ParseDelegate<T> parse = ParseDelegateStore<T>.Parse;
        if (parse == null)
        {
            parse = (ParseDelegate<T>)Delegate.CreateDelegate(typeof(ParseDelegate<T>), typeof(T), "Parse", true);
            ParseDelegateStore<T>.Parse = parse;
        }
        return parse(s);
    }

    public static bool TryParse<T>(string s, out T result)
    {
        TryParseDelegate<T> tryParse = ParseDelegateStore<T>.TryParse;
        if (tryParse == null)
        {
            tryParse = (TryParseDelegate<T>)Delegate.CreateDelegate(typeof(TryParseDelegate<T>), typeof(T), "TryParse", true);
            ParseDelegateStore<T>.TryParse = tryParse;
        }
        return tryParse(s, out result);
    }

I know other way than doing:

object x;
if (theType==typeof(int))
   x = int.parse(myString);
else if (theType==typeof(bool))
  x = bool.Parse(myString);
// and so on for other types..

Also note that the serialized data must contain the type names because you otherwise have no chance to know if "123" is of type int or unsigned short or whatever, or if for example "Red" is an enum value, a Color object or a string.

You can use an XmlSerializer or BinaryFormatter to serialize / deserialize your objects, which does all this logic already for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM