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