Estou tentando fazer alguma conversão de dados. Infelizmente, muitos dos dados estão em strings, onde devem ser int's ou duplos, etc ...
Então, o que eu tenho é algo como:
double? amount = Convert.ToDouble(strAmount);
O problema com essa abordagem é que se strAmount estiver vazio, se estiver vazio, quero que o valor seja nulo; portanto, quando o adiciono ao banco de dados, a coluna será nula. Então acabei escrevendo isso:
double? amount = null;
if(strAmount.Trim().Length>0)
{
amount = Convert.ToDouble(strAmount);
}
Agora isso funciona bem, mas agora tenho cinco linhas de código em vez de uma. Isso torna as coisas um pouco mais difíceis de ler, especialmente quando tenho uma grande quantidade de colunas para converter.
Eu pensei que usaria uma extensão para a classe string e os genéricos para passar o tipo, isso ocorre porque poderia ser um duplo, um int ou um longo. Então eu tentei isso:
public static class GenericExtension
{
public static Nullable<T> ConvertToNullable<T>(this string s, T type) where T: struct
{
if (s.Trim().Length > 0)
{
return (Nullable<T>)s;
}
return null;
}
}
Mas recebo o erro: Não é possível converter o tipo 'string' para 'T?'
Existe uma maneira de contornar isso? Não estou muito familiarizado com a criação de métodos usando genéricos.
fonte
Respostas:
Outra coisa a ter em mente é que a própria string pode ser nula.
fonte
Você pode tentar usar o método de extensão abaixo:
Dessa forma, você pode fazer isso:
fonte
Que tal isso:
Obviamente, isso não leva em consideração a falha na conversão.
fonte
Eu escrevi este conversor de tipo genérico. Ele funciona com valores nulos e padrão, convertendo entre todos os tipos conversíveis - não apenas com strings. Ele lida com todos os tipos de cenários que você esperaria (valores padrão, valores nulos, outros valores, etc ...)
Uso isso há cerca de um ano em dezenas de programas de produção, portanto deve ser bem sólido.
fonte
OutOfMemoryException
se você não puder reduzi-lo a um conjunto fixo de tipos de exceção.Você pode tentar:
faça sua própria verificação nula e retorne,
int?
se necessário. Você também deseja agrupar isso em umtry {}
fonte
Dê a isso uma chance ...
Então chame assim ...
fonte
Gosto da resposta de Joel, mas a modifiquei um pouco, pois não sou fã de comer exceções.
fonte
Você pode usar o seguinte com objetos, infelizmente isso não funciona com cadeias de caracteres.
Eu o uso para agrupar uma variável de sessão em uma propriedade (em uma página base). Portanto, meu uso real é (na minha página base):
Eu sou capaz de verificar se há nulo na lógica da página:
fonte
CType(Object, Nullable(Of Double))
funciona bem com cordasNão há como contornar isso. Anulável, assim como seu método, é restrito a usar apenas tipos de valor como argumento. String é um tipo de referência e, portanto, é incompatível com esta declaração.
fonte
fonte
Existe uma solução genérica (para qualquer tipo). A usabilidade é boa, mas a implementação deve ser aprimorada: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/
Isso permite que você escreva um código muito limpo como este:
e também:
fonte
typeName.IndexOf
? Sério?) E comportamento estranho (aTryConvert
função mostrada nem sequer manipula valores nulos corretamente).Aqui está algo baseado na resposta aceita. Eu removi o try / catch para garantir que todas as exceções não sejam engolidas e não sejam tratadas. Também garantiu que a variável de retorno (na resposta aceita) nunca seja inicializada duas vezes por nada.
fonte
Meu exemplo para tipos anônimos:
fonte
Outra variação. Este
NotSupportedException
se o tipo não puder ser convertidostring
. Por exemplo, uma estrutura personalizada sem um conversor de tipos.(T?)null
se a sequência falhar ao analisar. Não é necessário verificar se há espaço nulo ou em branco.fonte
Vamos adicionar mais uma solução semelhante à pilha. Este também analisa enums, e parece bom. Muito seguro.
https://github.com/Pangamma/PangammaUtilities-CSharp/blob/master/PangammaUtilities/Extensions/ToNullableStringExtension.cs
fonte
A resposta genérica fornecida por " Joel Coehoorn " é boa.
Mas, essa é outra maneira sem usar esses
GetConverter...
outry/catch
blocos ... (não tenho certeza, mas isso pode ter um desempenho melhor em alguns casos):O uso é o seguinte:
fonte
TypeDescriptor.GetConverter
... códigos. Esta é apenas outra maneira.