Вы должны получить базовый тип, чтобы сделать это ...
Попробуйте, я успешно использовал с дженериками:
//Coalesce to get actual property type...
Type t = property.PropertyType();
t = Nullable.GetUnderlyingType(t) ?? t;
//Coalesce to set the safe value using default(t) or the safe type.
safeValue = value == null ? default(t) : Convert.ChangeType(value, t);
Я использую его в ряде мест в своем коде, один из примеров - вспомогательный метод, который я использую для преобразования значений базы данных в безопасном виде:
public static T GetValue<T>(this IDataReader dr, string fieldName)
{
object value = dr[fieldName];
Type t = typeof(T);
t = Nullable.GetUnderlyingType(t) ?? t;
return (value == null || DBNull.Value.Equals(value)) ?
default(T) : (T)Convert.ChangeType(value, t);
}
Вызывается с помощью:
string field1 = dr.GetValue<string>("field1");
int? field2 = dr.GetValue<int?>("field2");
DateTime field3 = dr.GetValue<DateTime>("field3");
Я написал серию постов в блоге, включая эту, на http://www.endswithsaurus.com/2010_07_01_archive.html (Прокрутите вниз до Приложения, @ JohnMacintyre фактически обнаружил ошибку в моем исходном коде, которая привела меня по тому же пути, что и вы. сейчас). После этого поста у меня есть пара небольших модификаций, которые также включают преобразование типов enum, так что если ваше свойство является Enum, вы все равно можете использовать тот же вызов метода. Просто добавьте строку, чтобы проверить типы перечислений, и вы приступите к гонкам, используя что-то вроде:
if (t.IsEnum)
return (T)Enum.Parse(t, value);
Обычно у вас есть какая-то проверка ошибок или использование TryParse вместо Parse, но вы получите картинку.