Created
April 6, 2011 20:29
-
-
Save jwcarroll/906456 to your computer and use it in GitHub Desktop.
Will map a string value to pretty much any primitive type. It also handles lists of values.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class ReflectionExtensions | |
{ | |
public static Boolean Implements<T>(this Type typeToCheck) | |
{ | |
return typeToCheck.Implements(typeof(T)); | |
} | |
public static Boolean Implements(this Type typeToCheck, Type typeToCheckFor) | |
{ | |
if (typeToCheck == null || typeToCheckFor == null) return false; | |
if (typeToCheck == typeToCheckFor) return true; | |
if (typeToCheckFor.IsInterface) | |
return typeToCheck.ImplementsInterface(typeToCheckFor); | |
else | |
return typeToCheckFor.IsAssignableFrom(typeToCheck); | |
} | |
private static Boolean ImplementsInterface<TInterface>(this Type typeToCheck) | |
{ | |
return typeToCheck.ImplementsInterface(typeof(TInterface)); | |
} | |
private static Boolean ImplementsInterface(this Type typeToCheck, Type typeToCheckFor) | |
{ | |
if (typeToCheck == null || typeToCheckFor == null) return false; | |
var implementsInterface = false; | |
if (typeToCheckFor.IsGenericType) | |
{ | |
implementsInterface = typeToCheck.GetInterfaces().Any(x => | |
x.IsGenericType && | |
x.GetGenericTypeDefinition() == typeToCheckFor); | |
} | |
else | |
{ | |
implementsInterface = typeToCheckFor.IsAssignableFrom(typeToCheck); | |
} | |
return implementsInterface; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Tries to convert a string value into the type specified. Handles | |
/// most primitive types, as well as the ability to convert comma | |
/// delimited values into collections, so long as the individual values | |
/// are one of the supported types. | |
/// </summary> | |
/// <example> | |
/// Int32 myInt = 0; | |
/// TryConvertValue("1", typeof(Int32), out myInt); | |
/// | |
/// List<Int32> myIntList = null; | |
/// TryConvertValue("1,2,3,4,5", typeof(List<Int32>), out myIntList); | |
/// </example> | |
/// <param name="rawValue">The raw string value to be converted.</param> | |
/// <param name="type">The type that you want to convert the string to.</param> | |
/// <param name="value">The final converted value.</param> | |
/// <returns>True if the conversion is successful</returns> | |
private Boolean TryConvertValue(String rawValue, Type type, out Object value) | |
{ | |
value = null; | |
var success = false; | |
try | |
{ | |
if (type.IsEnum) | |
value = Enum.Parse(type, rawValue, true); | |
else if (type == typeof(Guid)) | |
value = Guid.Parse(rawValue); | |
else if (type.IsArray) | |
value = CreateArray(type, rawValue); | |
else if (type.Implements<IList>()) | |
value = CreateCollection(type, rawValue); | |
else if (type.Implements(typeof(ICollection<>))) | |
value = CreateCollection(type, rawValue); | |
else | |
value = Convert.ChangeType(rawValue, type); | |
success = true; | |
} | |
catch (Exception ex) | |
{ | |
Log.Exception(EventID.SettingsServiceConversionFailed, ex); | |
} | |
return success; | |
} | |
private object CreateArray(Type type, string rawValue) | |
{ | |
Type listElementTypeParam = type.GetElementType(); | |
var values = rawValue.Split(','); | |
var array = Array.CreateInstance(listElementTypeParam, values.Length); | |
for (int i = 0; i < array.Length; i++ ) | |
{ | |
Object val = null; | |
if (TryConvertValue(values[i], listElementTypeParam, out val)) | |
array.SetValue(val, i); | |
} | |
return array; | |
} | |
private object CreateCollection(Type type, string rawValue) | |
{ | |
Type collectionElementTypeParam = null; | |
if (type.IsGenericType) | |
collectionElementTypeParam = type.GetGenericArguments()[0]; | |
dynamic collection = Activator.CreateInstance(type); | |
foreach (var value in rawValue.Split(',')) | |
{ | |
dynamic objVal = null; | |
if (collectionElementTypeParam != null && TryConvertValue(value, collectionElementTypeParam, out objVal)) | |
collection.Add(objVal); | |
else | |
collection.Add(value); | |
} | |
return collection; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment