Super-Easy String to Anything

By Rob on Wednesday, September 10, 2008

1 Comment

Filed Under: .Net

I don’t think I’ve seen a single project without some form of string parsing: int.Parse(txtName.Text), anyone?.

Here’s a cool way to take a string and parse it to whatever you want, enum, double, bool, it works on anything that’s both IConvertible and a struct (ok I lied about “anything”). It’s an extension method, but could just be a library call if that pleases you (or your compiler) more.

 

public static T? As<T>(this string s) where T : struct, IConvertible
{
    try
    {
        Type type = typeof(T);
        bool isEnum = typeof(Enum).IsAssignableFrom(type);
        return (T)(isEnum
            ? Enum.Parse(type, s, true)
            : Convert.ChangeType(s, type));
    }
    catch
    {
        return null;
    }
}

Note that it just returns null if the parse fails – this actually ends up being really simple to use:

  • If you KNOW the parse shouldn’t fail, you just call .Value – which will give you an exception if the parse somehow did fail (this is a good thing)
  • If you want to see if the parse failed, you can check the .HasValue property
  • If you want to provide a fallback value, you can just use the ?? operator


Here are the TDD tests for the code, to give you idea of how flexible this is:


[TestMethod]
public void StringAsInt()
{
    Assert.AreEqual(5, "5".As<int>());
    Assert.AreEqual(25, "25".As<int>());
    Assert.AreEqual(null, "foobar".As<int>());
}

[TestMethod]
public void StringAsDouble()
{
    Assert.AreEqual(5.5, "5.5".As<double>());
    Assert.AreEqual(-25.2, "-25.2".As<double>());
    Assert.AreEqual(null, "foobar".As<double>());
}

[TestMethod]
public void StringAsBool()
{
    Assert.AreEqual(true, "true".As<bool>());
    Assert.AreEqual(false, "false".As<bool>());
    Assert.AreEqual(null, "foobar".As<bool>());
}

[TestMethod]
public void StringParseEnum()
{
    Assert.AreEqual(ContactPreference.Email, "Email".As<ContactPreference>());
    Assert.AreEqual(null, "Schmemail".As<ContactPreference>());
    Assert.AreEqual(null, ((string)null).As<ContactPreference>());
    Assert.AreEqual(ContactPreference.MobilePhone, "MobilePhone".As<ContactPreference>());
}
enum ContactPreference
{
    Email,
    MobilePhone
}

Enjoy! – Rob

One Comment for this post

Daniel

Nice! But how about using type.IsEnum, and have you considered TypeConverters for extra flexibility, or is that too slow?

Posted onNovember 27th, 2008 at 1:21 am

Leave a comment

Name (required) Comment
Mail (required)
Website