Unfortunately the table.CreateInstance() is a fairly naive method and fails for Enums (among other things). I ended up writing an extension method for table that uses reflection to interrogate the object instance it is trying to create. The nice thing about this approach is that the method will only overwrite the instance values that are specified in the table columns, however, you have to call it for each row of the table and pass in an already instantiated instance. It could be easily modified to act just like the CreateInstance method, but for my purposes, this worked better...
public static class TableExtensions
{
public static void FillInstance(this Table table, TableRow tableRow, object instance) {
var propertyInfos = instance.GetType().GetProperties();
table.Header.Each(header => Assert.IsTrue(propertyInfos.Any(pi => pi.Name == header), "Expected to find the property [{0}] on the object of type [{1}]".FormatWith(header, instance.GetType().Name)));
var headerProperties = table.Header.Select(header => propertyInfos.Single(p => p.Name == header)).ToList();
foreach (var propertyInfo in headerProperties) {
object propertyValue = tableRow[propertyInfo.Name];
var propertyType = propertyInfo.PropertyType;
if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
propertyType = propertyType.GetGenericArguments().Single();
}
var parse = propertyType.GetMethod("Parse", new[] { typeof(string) });
if (parse != null) {
// ReSharper disable RedundantExplicitArrayCreation
try {
propertyValue = propertyType.Name.Equals("DateTime") ? GeneralTransformations.TranslateDateTimeFrom(propertyValue.ToString()) : parse.Invoke(null, new object[] { propertyValue });
} catch (Exception ex) {
var message = "{0}\r\nCould not parse value: {2}.{3}(\"{1}\")".FormatWith(ex.Message, propertyValue, parse.ReturnType.FullName, parse.Name);
throw new Exception(message, ex);
}
// ReSharper restore RedundantExplicitArrayCreation
}
propertyInfo.SetValue(instance, propertyValue, null);
}
}
}
And you could invoke it as follows:
ObjectDTO objectDTO;
foreach (var tableRow in table.Rows)
{
objectDTO = table.FillInstance(tableRow, new ObjectDTO());
//Do individual row processing/testing here...
}