As outras respostas até agora estão todas corretas; Eu só queria adicionar mais um pouco mais limpo:
v2 = v1 ??default(int);
Qualquer um Nullable<T>é implicitamente conversível T, desde que a expressão inteira que está sendo avaliada nunca possa resultar em uma atribuição nula a um ValueType. Portanto, o operador coalescente nulo ??é apenas açúcar de sintaxe para o operador ternário:
v2 = v1 ==null?default(int): v1;
... que por sua vez é açúcar de sintaxe para um if / else:
if(v1==null)
v2 =default(int);else
v2 = v1;
Além disso, a partir do .NET 4.0, Nullable<T>possui um método "GetValueOrDefault ()", que é um getter com segurança nula que basicamente executa a coalescência nula mostrada acima, portanto, isso também funciona:
É default(int)realmente necessário? O que há de errado com um simples 0?
Cole Johnson
4
Funcionaria para este exemplo, mas, no caso geral, é recomendável usar defaultonde for apropriado. Zero nem sempre é válido como um valor, muito menos o padrão, portanto, se você substituirint por um genérico, Tverá que meu código funciona enquanto zero não. Em alguma versão futura do framework, defaulttambém pode se tornar sobrecarregável; se e quando isso acontecer, o código usando o padrão poderá tirar vantagem facilmente, enquanto as atribuições nulas ou zero explícitas precisarão ser alteradas.
Keiths
5
Isso deve subir para o topo: .NET 4.0, Nullable <T> possui um "GetValueOrDefault ()"
RandomHandle
Obrigado por voltar para editá-lo com GetValueOrDefault!
CindyH
Você pode ter cuidado com o DateTime ao usar o padrão. Isso pode inserir a data padrão em vez de vazia.
Além disso, se você não tiver certeza se a v1 contém nulo, pode usar o operador coalescente para definir um valor de fallback. Por exemplo, v2 = v1 ?? 0;
Arjen
12
E não deixe de conferir v1.HasValueprimeiro.
Yuck
3
O MSDN diz que isso gerará uma exceção se ov1 houver null. Na minha opinião, esta não é uma resposta correta.
ventiseis
6
@ventiseis Eu acho que esse é um comportamento desejável - Estou surpreso que muitas das outras respostas sejam aceitáveis ao converter silenciosamente um nulo para 0. Se você estiver atribuindo um tipo nulo a um tipo não nulo, deve ter certeza de que o valor não é realmente nulo. O OP não disse "Quero atribuir v1 a v2 ou 0 se v1 for nulo", mas é o que todos pareciam assumir
Uma conversão simples entre v1e v2não é possível porque v1possui um domínio de valores maior que v2. É tudo o que v1pode aguentar mais o nullestado. Para converter, você precisa declarar explicitamente em que valor intserá usado para mapear o nullestado. A maneira mais simples de fazer isso é o ??operador
v2 = v1 ??0;// maps null of v1 to 0
Isso também pode ser feito de forma longa
int v2;if(v1.HasValue){
v2 = v1.Value;}else{
v2 =0;}
Dependendo do contexto de uso, você pode usar o recurso de correspondência de padrões do C # 7:
int? v1 =100;if(v1 isint v2){Console.WriteLine($"I'm not nullable anymore: {v2}");}
EDITAR:
Como algumas pessoas estão votando sem deixar uma explicação, eu gostaria de adicionar alguns detalhes para explicar a lógica de incluir isso como uma solução viável.
A correspondência de padrões do C # 7 agora nos permite verificar o tipo de um valor e convertê-lo implicitamente. No snippet acima, a condição if somente passará quando o valor armazenado v1for compatível com o tipo do tipo for v2, que nesse caso é int. Daqui resulta que, quando o valor for v1for null, a condição if falhará, pois null não pode ser atribuído a um int. Mais corretamente, nullnão é um int.
Gostaria de destacar que o fato de que essa solução nem sempre é a melhor opção. Como sugiro, acredito que isso dependerá do contexto de uso exato do desenvolvedor. Se você já possui um int?e deseja operar condicionalmente em seu valor se e somente se o valor atribuído não for nulo (este é o único momento em que é seguro converter um int nulo em um int regular sem perder informações), a correspondência de padrões é talvez uma das maneiras mais concisas de fazer isso.
A necessidade de introduzir um novo nome de variável é lamentável, mas esta é a melhor solução (mais segura) se não houver valor padrão, porque não há risco de refatorar acidentalmente suas HasValueverificações.
minexew
Eu simplesmente não vejo nenhuma vantagem nesse método sobre v1.HasValue como a verificação e, em seguida, v1.Value para acessar o valor subjacente. Eu não descartaria isso, mas acho que esse problema já foi resolvido e uma nova técnica não adiciona muita clareza ao problema. Eu também o comparei como 8-9% mais lento.
Brandon Barkley
Obrigado por compará-lo, é bom saber! De qualquer maneira, a diferença é marginal, na melhor das hipóteses (a menos que você faça isso em alguma área crítica do tempo, suponho). Considero isso mais "conciso" ou possivelmente "idiomático", pois se baseia em açúcares de sintaxe inseridos na linguagem em vez de APIs. É um pouco subjetivo, mas talvez seja "mais sustentável". Embora seja verdade, eu gosto mais dessa abordagem do que depender de um valor padrão, como sugerem muitas outras respostas.
Nicholas Miller
3
Ele atribuirá o valor de v1a v2se não for nulo, caso contrário, o valor padrão será zero.
Embora esse código possa responder à pergunta, fornecer um contexto adicional a respeito de por que e / ou como esse código responde à pergunta melhora seu valor a longo prazo.
Ao responder a uma pergunta de oito anos com quinze respostas existentes, é importante explicar qual é o novo aspecto da pergunta que sua resposta está abordando e observar se a passagem do tempo mudou a resposta. As respostas somente de código quase sempre podem ser aprimoradas com a adição de algumas explicações.
v1
énull
?Respostas:
As outras respostas até agora estão todas corretas; Eu só queria adicionar mais um pouco mais limpo:
Qualquer um
Nullable<T>
é implicitamente conversívelT
, desde que a expressão inteira que está sendo avaliada nunca possa resultar em uma atribuição nula a um ValueType. Portanto, o operador coalescente nulo??
é apenas açúcar de sintaxe para o operador ternário:... que por sua vez é açúcar de sintaxe para um if / else:
Além disso, a partir do .NET 4.0,
Nullable<T>
possui um método "GetValueOrDefault ()", que é um getter com segurança nula que basicamente executa a coalescência nula mostrada acima, portanto, isso também funciona:fonte
default(int)
realmente necessário? O que há de errado com um simples0
?default
onde for apropriado. Zero nem sempre é válido como um valor, muito menos o padrão, portanto, se você substituirint
por um genérico,T
verá que meu código funciona enquanto zero não. Em alguma versão futura do framework,default
também pode se tornar sobrecarregável; se e quando isso acontecer, o código usando o padrão poderá tirar vantagem facilmente, enquanto as atribuições nulas ou zero explícitas precisarão ser alteradas.Como isso,
fonte
Você pode usar a propriedade Value para atribuição.
fonte
v1.HasValue
primeiro.v1
houvernull
. Na minha opinião, esta não é uma resposta correta.Tudo o que você precisa é..
fonte
Se você sabe que
v1
tem um valor, pode usar aValue
propriedade:O uso do
GetValueOrDefault
método atribuirá o valor se houver um, caso contrário, o padrão para o tipo ou um valor padrão que você especificar:Você pode usar a
HasValue
propriedade para verificar sev1
tem um valor:Também há suporte ao idioma para o
GetValueOrDefault(T)
método:fonte
Você não pode fazer isso se a v1 for nula, mas você pode verificar com um operador.
fonte
recupera o valor do objeto. Se for nulo, ele retornará o valor padrão de int, que é 0.
Exemplo:
fonte
Se o valor padrão para um determinado tipo for um resultado aceitável:
Se você desejar um valor padrão diferente quando o resultado for indefinido:
Se você deseja apenas o valor retornado (não importa se o método falhou ou não):
.NET 4.7.2 .:
GetValueOrDefault()
retorna o valor do campo sem nenhuma verificação.fonte
Para mim, a melhor solução é usar o
GetValueOrDefault()
métodofonte
A conversão int anulável em int pode ser feita da seguinte maneira:
fonte
é possível com
v2 = Convert.ToInt32(v1);
fonte
Você poderia fazer
fonte
Uma conversão simples entre
v1
ev2
não é possível porquev1
possui um domínio de valores maior quev2
. É tudo o quev1
pode aguentar mais onull
estado. Para converter, você precisa declarar explicitamente em que valorint
será usado para mapear onull
estado. A maneira mais simples de fazer isso é o??
operadorIsso também pode ser feito de forma longa
fonte
Dependendo do contexto de uso, você pode usar o recurso de correspondência de padrões do C # 7:
EDITAR:
Como algumas pessoas estão votando sem deixar uma explicação, eu gostaria de adicionar alguns detalhes para explicar a lógica de incluir isso como uma solução viável.
A correspondência de padrões do C # 7 agora nos permite verificar o tipo de um valor e convertê-lo implicitamente. No snippet acima, a condição if somente passará quando o valor armazenado
v1
for compatível com o tipo do tipo forv2
, que nesse caso éint
. Daqui resulta que, quando o valor forv1
fornull
, a condição if falhará, pois null não pode ser atribuído a umint
. Mais corretamente,null
não é umint
.Gostaria de destacar que o fato de que essa solução nem sempre é a melhor opção. Como sugiro, acredito que isso dependerá do contexto de uso exato do desenvolvedor. Se você já possui um
int?
e deseja operar condicionalmente em seu valor se e somente se o valor atribuído não for nulo (este é o único momento em que é seguro converter um int nulo em um int regular sem perder informações), a correspondência de padrões é talvez uma das maneiras mais concisas de fazer isso.fonte
HasValue
verificações.Ele atribuirá o valor de
v1
av2
se não for nulo, caso contrário, o valor padrão será zero.Ou abaixo é a outra maneira de escrevê-lo.
fonte
No C # 7.1 e posterior, o tipo pode ser inferido usando o
default
literal em vez dodefault
operador, para que possa ser escrito da seguinte maneira:fonte
fonte