Я строю произвольные объекты из DataRows с помощью Reflection, и когда резина наконец встречает дорогу, мне нужно взять значение из DataRow и присвоить его свойству объекта.
Поскольку в DataRows могут быть типы, которые не поддерживают преобразование, многие из них приводят к исключениям, которые необходимо обработать. Например, DBnulls может заползти в DataRow или какой-либо числовой формат, который не преобразуется в другой, и т. Д. Есть ли способ избежать исключений? (Я не приму проверку гигантских операторов переключения для каждой комбинации типов в свойстве целевого объекта и исходных данных.)
public void Merge(DataRow data)
{
PropertyInfo[] props = this.GetType().GetProperties(BindingFlags...);
foreach (PropertyInfo pi in props.Where(p => T_IsPrimitive(p.PropertyType)))
{
object src = null;
if( dataAsDataRow.Table.Columns.Contains(pi.Name) )
src = ((DataRow)data)[pi.Name];
if (src != null)
{
if( src.GetType() != pi.PropertyType ) {
try {
src = Convert.ChangeType(src, pi.PropertyType);
} catch(InvalidCastException e) {
try { src = Convert.ChangeType(src.ToString(), pi.PropertyType); }
catch { throw e; }
}
}
pi.SetValue(this, src, null);
}
}
}
public bool T_IsPrimitive(Type t)
{
return t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) ||
t == typeof(DateTime) || t == typeof(TimeSpan)
}
Так есть ли способ посмотреть, прежде чем я прыгну с этими ChangeType
преобразованиями?
РЕШЕНИЕ
Благодаря Стеце, вот что я придумала:
if( src.GetType() != pi.PropertyType ) {
object converted = null;
TypeConverter converter = TypeDescriptor.GetConverter(pi.PropertyType);
if( converter != null ) {
if( converter.CanConvertFrom(vType) )
converted = converter.ConvertFrom(src);
else if( converter.CanConvertFrom(typeof(String)) )
converted = converter.ConvertFrom(src.ToString());
}
src = converted;
}
if( src != null )
pi.SetValue(this, src, null);
Логически эквивалентный, элегантный, и больше никаких исключений!