Estava dando manutenção em um código que basicamente validava 30 campos com a seguinte regra.
Se o campo for vazio passar nulo para a procedure
Senão for validar se o campo é do tipo esperado (DateTime, Numeric, etc).
Basicamente o código era igual ao abaixo para cada campo.
string valor = “20/01/01”;
DateTime? data = null;
DateTime dataTemp;
if( (!string.IsNullOrEmpty(valor)) && DateTime.TryParse(valor, out dataTemp))
{
data = new Nullable<DateTime>(dataTemp);
}
Então resolvi cria uma função genérica e fazer testes de performance, para verificar qual solução implementar na solução. Veja as opções , ambas bem extensas =)
static bool TryParseException<T>(string text, out T value)
{
value = default(T);
try
{
value = (T)Convert.ChangeType(text, typeof(T));
return true;
}
catch
{
return false;
}
}
public static bool TryParseReflection<T>(string input, out T value) where T : struct
{
var type = typeof(T);
value = default(T);
var method = type.GetMethod(
“TryParse”,
new[] { typeof(string), Type.GetType(string.Format(“{0}&”, type.FullName)) });
return (bool)method.Invoke(null, new object[] { input, value });
}
Para os campos com valores compativeis com o tipo esperado a versão com Exception foi mais rápida, claro que era esperado porque com o valor esta no formato esperado não é disparada nenhum exception. Comparativo para 30 campos (0,015 s X 0.062 s)
Agora quandos os valores não são compativeis a versão que usa Reflection é infinitamente mais rápida. Comparativo para 30 campos (0,003 s X 1.5 s)
Pelos meus testes é bem mais interessante utilizar a versão com Reflection, pois mesmo quando é mais lenta é uma diferença que um usuário não perceberá a diferença.
Claro que se você for processar milhões de registros e 99.99% for o tipo correto seja mais interessante utilizar a versão com Exception =)