Eu estou querendo analisar uma seqüência de caracteres em um int anulável em c #. ie Eu quero voltar o valor int da string ou null se não puder ser analisado.
Eu meio que esperava que isso funcionasse
int? val = stringVal as int?;
Mas isso não vai funcionar, então o jeito que eu estou fazendo isso agora é que eu escrevi esse método de extensão
public static int? ParseNullableInt(this string value)
{
if (value == null || value.Trim() == string.Empty)
{
return null;
}
else
{
try
{
return int.Parse(value);
}
catch
{
return null;
}
}
}
Existe um jeito melhor de fazer isso?
Edição: Obrigado pelas sugestões TryParse, eu sabia sobre isso, mas funcionou sobre o mesmo. Estou mais interessado em saber se existe um método de estrutura interno que será analisado diretamente em um int nulo?
Respostas:
int.TryParse
é provavelmente um pouco mais fácil:Editar @Glenn
int.TryParse
é "incorporado à estrutura". É eint.Parse
é o caminho para analisar cadeias de caracteres para ints.fonte
Você pode fazer isso em uma linha, usando o operador condicional e o fato de poder converter
null
para um tipo nulo (duas linhas, se você não tiver um int pré-existente, poderá reutilizar para a saída deTryParse
):Pré C # 7:
Com a sintaxe atualizada do C # 7 que permite declarar uma variável de saída na chamada de método, isso fica ainda mais simples.
fonte
int.TryParse(val, out i) ? i : default(int?);
[ Atualizado para usar o C # moderno conforme a sugestão do @ sblom]
Eu tive esse problema e acabei com isso (afinal, an
if
e 2return
s são muito longos!):Em uma observação mais séria, tente não misturar
int
, que é uma palavra-chave C #, comInt32
, que é do tipo .NET Framework BCL - embora funcione, apenas torna o código confuso.fonte
int i;
linha e apenas ir comreturn int.TryParse (val, out var i) ? (int?) i : null;
int? ParseNInt (string val) => int.TryParse (val, out var i) ? (int?) i : null;
Existe essa abordagem que analisará diretamente um int nulo (e não apenas int) se o valor for válido como uma seqüência nula ou vazia, mas lança uma exceção para valores inválidos, portanto você precisará capturar a exceção e retornar o valor padrão para essas situações:
Essa abordagem ainda pode ser usada para análises não anuláveis e anuláveis:
Nota: existe um método IsValid no conversor que você pode usar em vez de capturar a exceção (exceções lançadas resultam em sobrecarga desnecessária, se esperado). Infelizmente, ele só funciona desde o .NET 4, mas ainda existe um problema em que ele não verifica seu código do idioma ao validar os formatos corretos de DateTime, veja o bug 93559 .
fonte
Fontes:
fonte
Tópico antigo, mas que tal:
Eu gosto mais disso como o requisito de analisar nulo, a versão TryParse não geraria um erro, por exemplo, em ToNullableInt32 (XXX). Isso pode introduzir erros silenciosos indesejados.
fonte
int
, ela deve retornarnull
, não lançar uma exceção.Tente o seguinte:
fonte
Sinto que minha solução é uma solução muito limpa e agradável:
Obviamente, essa é uma solução genérica que exige apenas que o argumento genérico tenha um método estático "Parse (string)". Isso funciona para números, booleano, DateTime etc.
fonte
Você pode esquecer todas as outras respostas - existe uma ótima solução genérica: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/
Isso permite que você escreva um código muito limpo como este:
e também:
fonte
O seguinte deve funcionar para qualquer tipo de estrutura. É baseado no código de Matt Manela nos fóruns do MSDN . Como Murph aponta, o tratamento de exceções pode ser caro comparado ao uso do método TryParse de Tipos dedicado.
Esses foram os casos de teste básicos que eu usei.
fonte
Eu sugeriria os seguintes métodos de extensão para análise de string no valor int com capacidade de definir o valor padrão, caso a análise não seja possível:
fonte
Esta solução é genérica sem sobrecarga de reflexão.
fonte
IsNullOrEmpty
comIsNullOrWhitespace
Não existe.
fonte
Eu senti que deveria compartilhar o meu, que é um pouco mais genérico.
Uso:
Solução:
A primeira versão é mais lenta, pois requer uma tentativa de captura, mas parece mais limpa. Se não for chamado muitas vezes com cadeias inválidas, isso não é importante. Se o desempenho for um problema, observe que, ao usar os métodos TryParse, você precisa especificar o parâmetro type de ParseBy, pois não pode ser inferido pelo compilador. Também tive que definir um delegado como a palavra-chave out não pode ser usada no Func <>, mas pelo menos desta vez o compilador não requer uma instância explícita.
Finalmente, você pode usá-lo com outras estruturas, como decimal, DateTime, Guid, etc.
fonte
Encontrei e adaptei algum código para uma classe NullableParser genérica. O código completo está no meu blog Nullable TryParse
fonte
fonte
Você nunca deve usar uma exceção se não precisar - a sobrecarga é horrível.
As variações no TryParse resolvem o problema - se você quiser ser criativo (para tornar seu código mais elegante), provavelmente poderá fazer algo com um método de extensão na versão 3.5, mas o código será mais ou menos o mesmo.
fonte
Usando delegados, o código a seguir poderá fornecer reutilização se você precisar da análise anulável para mais de um tipo de estrutura. Eu mostrei as versões .Parse () e .TryParse () aqui.
Este é um exemplo de uso:
E aqui está o código que leva você até lá ...
fonte
Sei que esse é um tópico antigo, mas você não pode simplesmente:
?
fonte
Eu criei este, que atendeu aos meus requisitos (eu queria que meu método de extensão emulasse o mais próximo possível do retorno do TryParse da estrutura, mas sem os blocos try {} catch {} e sem o compilador reclamar tipo anulável dentro do método de estrutura)
fonte
Eu sugiro o código abaixo. Você pode trabalhar com exceção, quando ocorreu um erro de conversão.
Use este método de extensão no código (fill int? Age propriedade de uma classe de pessoa):
OU
fonte