Atravessou esta linha de código:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
O que significam os dois pontos de interrogação, é algum tipo de operador ternário? É difícil procurar no Google.
c#
null-coalescing-operator
Edward Tanguay
fonte
fonte
Respostas:
É o operador coalescente nulo e bem como o operador ternário (se-imediato). Veja também ?? Operador - MSDN .
expande para:
que se expande ainda mais para:
Em inglês, significa "Se o que estiver à esquerda não for nulo, use-o; caso contrário, use o que está à direita".
Observe que você pode usar qualquer número destes em sequência. A seguinte declaração irá atribuir o primeiro não-nula
Answer#
paraAnswer
(se todas as respostas são nulos então oAnswer
é null):Também vale a pena mencionar, enquanto a expansão acima é conceitualmente equivalente, o resultado de cada expressão é avaliado apenas uma vez. Isso é importante se, por exemplo, uma expressão for uma chamada de método com efeitos colaterais. (Agradecemos a @Joey por apontar isso.)
fonte
??
é deixado associativo, entãoa ?? b ?? c ?? d
é equivalente a((a ?? b) ?? c ) ?? d
. "Os operadores de atribuição e o operador ternário (? :) são associativos à direita. Todos os outros operadores binários são associativos à esquerda." Fonte: msdn.microsoft.com/pt-br/library/ms173145.aspxSó porque ninguém mais disse as palavras mágicas ainda: é o operador coalescente nulo . É definido na seção 7.12 da especificação de idioma do C # 3.0 .
É muito útil, principalmente devido ao modo como funciona quando é usado várias vezes em uma expressão. Uma expressão do formulário:
dará o resultado da expressão
a
se for não nulo; caso contráriob
, tentec
, caso contrário, tente , caso contrário, tented
. Curto-circuito em todos os pontos.Além disso, se o tipo de
d
for não nulo, o tipo de toda a expressão também não será nulo.fonte
É o operador coalescente nulo.
http://msdn.microsoft.com/en-us/library/ms173224.aspx
Sim, quase impossível procurar, a menos que você saiba como é chamado! :-)
EDIT: E este é um recurso interessante de outra pergunta. Você pode encadeá-los.
Recursos ocultos do c #?
fonte
Obrigado a todos, aqui está a explicação mais sucinta que encontrei no site do MSDN:
fonte
-1
é apenas uma planícieint
, que não é anulável).x
é do tipoint?
, masy
é do tipoint
, você pode escreverint y = (int)(x ?? -1)
. Ele irá analisarx
a umint
, se não énull
, ou atribuir-1
ay
sex
énull
.??
existe para fornecer um valor para um tipo anulável quando o valor é nulo. Portanto, se formsAuth for nulo, ele retornará novo FormsAuthenticationWrapper ().fonte
Os dois pontos de interrogação (??) indicam que é um operador de coalescência.
O operador coalescente retorna o primeiro valor NON-NULL de uma cadeia. Você pode ver este vídeo do youtube que demonstra praticamente tudo.
Mas deixe-me adicionar mais ao que o vídeo diz.
Se você vir o significado em inglês de coalescer, ele diz "consolidar juntos". Por exemplo, abaixo, está um código coalescente simples que encadeia quatro cadeias.
Então, se
str1
énull
que vai tentarstr2
, sestr2
énull
que vai tentarstr3
e assim por diante até encontrar uma string com um valor não nulo.Em palavras simples, o operador Coalescing retorna o primeiro valor NON-NULL de uma cadeia.
fonte
É mão curta para o operador ternário.
Ou para aqueles que não fazem ensino ternário:
fonte
!= null
) quanto o segundoformsAuth
(após o?
) podem ser alterados; na forma de coalescência nula, ambos assumem implicitamente os valores que você forneceu.Se você conhece Ruby,
||=
parece C #??
para mim. Aqui estão alguns Ruby:E em C #:
fonte
x ||= y
desugars para algo comox = x || y
, então??
é realmente mais parecido com o plain||
em Ruby.??
só se preocupanull
, enquanto que o||
operador em Ruby, como na maioria dos idiomas, é mais sobrenull
,false
ou qualquer coisa que pode ser considerado um booleano com um valor defalse
(por exemplo, em algumas línguas,""
). Isso não é uma coisa boa ou ruim, apenas uma diferença.operador coalescente
é equivalente a
fonte
Nada de perigoso nisso. De fato, é lindo. Você pode adicionar um valor padrão se isso for desejável, por exemplo:
CÓDIGO
fonte
int? x1 = null;
Está certox1
-x4
DEVE ser do tipo anulável: não faz sentido dizer, efetivamente, "o resultado é0
sex4
for um valor que ele não pode aceitar" (null
). "Tipo anulável" aqui inclui tipos de valores anuláveis e tipos de referência, é claro. É um erro em tempo de compilação se uma ou mais das variáveis encadeadas (exceto a última) não forem anuláveis.Como apontado corretamente em várias respostas, que é o "operador coalescente nulo" ( ?? ), falando sobre o qual você também pode querer conferir ao primo o "Operador nulo-condicional" ( ?. Ou ? [ ) Que é um operador que muitas vezes é usado em conjunto com ??
Operador nulo-condicional
Por exemplo:
o jeito antigo sem ? e ?? de fazer isso é
o que é mais detalhado e complicado.
fonte
Apenas para sua diversão (sabendo que todos vocês são C # guys ;-).
Eu acho que se originou em Smalltalk, onde existe há muitos anos. É definido lá como:
no objeto:
em UndefinedObject (também conhecido como classe nil):
Existem versões de avaliação (?) E não avaliação (??) disso.
É freqüentemente encontrado em métodos getter para variáveis privadas (instância) inicializadas preguiçosamente, que são deixadas nulas até serem realmente necessárias.
fonte
Alguns dos exemplos aqui de obtenção de valores usando coalescência são ineficientes.
O que você realmente quer é:
ou
Isso impede que o objeto seja recriado toda vez. Em vez de a variável privada permanecer nula e um novo objeto ser criado em cada solicitação, isso garante que a variável privada seja atribuída se o novo objeto for criado.
fonte
??
atalho não é avaliado?new FormsAuthenticationWrapper();
é avaliado se e somente se_formsAuthWrapper
for nulo.Nota:
Eu li todo este tópico e muitos outros, mas não consigo encontrar uma resposta tão completa quanto esta.
Pelo qual eu entendi completamente o "por que usar ?? e quando usar ?? e como usar ??."
Fonte:
Fundação de comunicação do Windows desencadeada Por Craig McMurtry ISBN 0-672-32948-4
Tipos de valor anulável
Há duas circunstâncias comuns em que alguém gostaria de saber se um valor foi atribuído a uma instância de um tipo de valor. A primeira é quando a instância representa um valor em um banco de dados. Nesse caso, alguém gostaria de poder examinar a instância para verificar se um valor está realmente presente no banco de dados. A outra circunstância, mais pertinente ao assunto deste livro, é quando a instância representa um item de dados recebido de alguma fonte remota. Novamente, gostaríamos de determinar a partir da instância se um valor para esse item de dados foi recebido.
O .NET Framework 2.0 incorpora uma definição de tipo genérico que fornece casos como esses nos quais se deseja atribuir nulo a uma instância de um tipo de valor e testar se o valor da instância é nulo. Essa definição de tipo genérico é System.Nullable, que restringe os argumentos de tipo genérico que podem ser substituídos por T para valorizar tipos. Instâncias de tipos construídos a partir de System.Nullable podem receber um valor nulo; de fato, seus valores são nulos por padrão. Assim, os tipos construídos a partir de System.Nullable podem ser chamados de tipos de valor anulável. System.Nullable possui uma propriedade, Value, pela qual o valor atribuído a uma instância de um tipo construído a partir dela pode ser obtido se o valor da instância não for nulo. Portanto, pode-se escrever:
A linguagem de programação C # fornece uma sintaxe abreviada para declarar tipos criados a partir de System.Nullable. Essa sintaxe permite abreviar:
para
O compilador impedirá que alguém tente atribuir o valor de um tipo de valor anulável a um tipo de valor comum desta maneira:
Isso impede que se faça isso porque o tipo de valor anulável poderia ter o valor nulo, o que realmente teria nesse caso, e esse valor não pode ser atribuído a um tipo de valor comum. Embora o compilador permita esse código,
A segunda instrução faria com que uma exceção fosse lançada porque qualquer tentativa de acessar a propriedade System.Nullable.Value é uma operação inválida se o tipo construído a partir de System.Nullable não recebeu um valor válido de T, o que não aconteceu neste caso.
Conclusão:
Uma maneira adequada de atribuir o valor de um tipo de valor nulo a um tipo de valor comum é usar a propriedade System.Nullable.HasValue para verificar se um valor válido de T foi atribuído ao tipo de valor nulo:
Outra opção é usar esta sintaxe:
Pelo qual o número inteiro ordinário myInteger é atribuído ao valor do número inteiro anulável "myNullableInteger" se este último recebeu um valor inteiro válido; caso contrário, myInteger recebe o valor de -1.
fonte
É um operador coalescente nulo que funciona de maneira semelhante a um operador ternário.
Outro ponto interessante para isso é: "Um tipo anulável pode conter um valor ou pode ser indefinido" . Portanto, se você tentar atribuir um tipo de valor nulo a um tipo de valor nulo, você receberá um erro em tempo de compilação.
Então, para fazer isso usando? operador:
fonte
é equivalente a
Mas o mais legal é que você pode prendê-los, como outras pessoas disseram. O que você não mencionou é que você pode realmente usá-lo para lançar uma exceção.
fonte
O
??
operador é chamado de operador de coalescência nula. Retorna o operando esquerdo se o operando não for nulo; caso contrário, ele retornará o operando do lado direito.Defina
variable2
como o valor devariable1
, sevariable1
NÃO for nulo; caso contrário, se forvariable1 == null
definidovariable2
como 100.fonte
Outros descreveram
Null Coalescing Operator
muito bem. Para os interessados, há uma sintaxe abreviada em que esta (a questão SO):FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
é equivalente a isso:
FormsAuth ??= new FormsAuthenticationWrapper();
Alguns acham mais legível e sucinto.
fonte