Seu código - como está agora - transferirá qualquer valor no nível da string . Esta é uma abordagem muito ruim . As conversões implícitas que ocorrem dependem muito das configurações do seu sistema (idioma e cultura). A pior parte é:isso pode funcionar muito bem em sua máquina enquanto você a está testando, mas no sistema de um cliente ele quebra com mensagens estranhas. Boa depuração :-(
Altere seu código assim
foreach (PropertyInfo prop in props) {
// Setting column names as Property names.
if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
dataTable.Columns.Add(prop.Name, prop.PropertyType.GetGenericArguments()[0]);
else
dataTable.Columns.Add(prop.Name, prop.PropertyType);
}
Isso adicionará a coluna - mesmo que seja um tipo anulável - com o tipo de dados correto.
créditos: Esta resposta me ajudou
ATUALIZAÇÃO Ainda mais simples
(thx para Yves M. em um comentário abaixo da resposta vinculada)
foreach (PropertyInfo prop in props) {
// Setting column names as Property names.
dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}