Here is an extension method for string that makes it easy - almost trivial - to convert the value held by the string into another type.

var s1 = "43";
int count = s1.As<int>();

var s2 = "Green";
Color foreground = s2.As<Color>();

var s3 = "10.2.44.0";
Version release = s3.As<Version>();

How does this work?

  • Check for the special case of conversion to a string, and just return the same value if required.
  • Use a TypeConverter to convert if one is available that can handle a string. This handles a bunch of simple types like int, bool, DateTime, TimeSpan, Color and most enum types.
  • If the target type has a constructor that takes a single string, create an instance by passing the value to that constructor. This handles some more complex classes like Version and provides another way for your own types to hook into the conversion process.

Because this method uses reflection, performance is relatively poor - you may not want to use it in its current form in the midst of a tight loop. Like all performance issues however, measure performance with a profiler before you make changes.

Here’s the source:

public static T As<T>(this string value)
{
    object v = value;

    // If a string, just return it
    if (typeof(T) == typeof(string))
    {
        return (T)v;
    }

    // Use a TypeConverter if one is available
    var converter = TypeDescriptor.GetConverter(typeof(T));
    if (converter != null && converter.CanConvertFrom(typeof(string)))
    {
        try
        {
            return (T)converter.ConvertFromString(value);
        }
        catch (Exception ex)
        {
            string failureMessage
                = string.Format(
                    CultureInfo.CurrentCulture,
                    "Failed to convert \"{0}\" to {1}: {2}",
                    value,
                    typeof(T).Name,
                    ex.Message);
            throw new InvalidOperationException(failureMessage);
        }
    }

    // Look for a constructor that takes a string
    var constructor 
        = typeof(T).GetConstructor(new[] { typeof(string) });
    if (constructor != null)
    {
        return (T)constructor.Invoke(new[] { value });
    }

    var message 
        = string.Format(
            CultureInfo.CurrentCulture, 
            "Cannot convert {0} into {1}", 
            value, 
            typeof(T).Name);
    throw new InvalidOperationException(message);
}

Comments

blog comments powered by Disqus
Next Post
Becoming a Better Developer  18 Sep 2014
Prior Post
FTP, Unicode and the inconvenient bug  28 Jun 2014
Related Posts
Browsers and WSL  31 Mar 2024
Factory methods and functions  05 Mar 2023
Using Constructors  27 Feb 2023
An Inconvenient API  18 Feb 2023
Method Archetypes  11 Sep 2022
A bash puzzle, solved  02 Jul 2022
A bash puzzle  25 Jun 2022
Improve your troubleshooting by aggregating errors  11 Jun 2022
Improve your troubleshooting by wrapping errors  28 May 2022
Keep your promises  14 May 2022
Archives
August 2014
2014