C ordem # lógica eo comportamento do compilador

votos
14

Em C #, (e sentir-se livre para responder para outros idiomas), que ordem é que o tempo de execução avaliar uma declaração lógica?

Exemplo:

DataTable myDt = new DataTable();
if (myDt != null && myDt.Rows.Count > 0)
{
    //do some stuff with myDt
}

Qual afirmação é que o tempo de execução avaliar em primeiro lugar -

myDt != null

ou:

myDt.Rows.Count > 0

?

Existe um momento em que o compilador jamais iria avaliar a declaração para trás? Talvez quando um operador OR está envolvido?


E é conhecido como um operador bit a bit lógico e será sempre avaliar todas as sub-expressões

O que é um bom exemplo de quando usar o operador bit a bit em vez do boolean curto-circuito?

Publicado 07/08/2008 em 21:30
fonte usuário
Em outras línguas...                            


18 respostas

votos
16

C #: Da esquerda para a direita, eo processamento pára se um não-jogo (avaliada como false) é encontrado.

Respondeu 07/08/2008 em 21:33
fonte usuário

votos
9

"C #: Da esquerda para a direita, eo processamento pára se um jogo (avaliada como verdadeira) é encontrado."

Zombie ovelhas é errado, rep não o suficiente para votar para baixo.

A pergunta é sobre o operador &&, não o || operador.

No caso de && avaliação vai parar se um FALSE é encontrado.

No caso de || avaliação pára se um verdadeiro é encontrado.

Respondeu 08/08/2008 em 07:51
fonte usuário

votos
8

Sei que esta pergunta já foi respondida, mas eu gostaria de jogar em outro bit de informação que está relacionado com o tema.

Em linguagens, como C ++, onde você pode realmente sobrecarregar o comportamento do && e || operadores, é altamente recomendável que você não faça isso . Isto porque, quando você sobrecarregar esse comportamento, você acaba forçando a avaliação de ambos os lados da operação. Isto faz duas coisas:

  1. Ele quebra o mecanismo de avaliação lenta devido a sobrecarga é uma função que tem de ser chamado e, portanto, ambos os parâmetros são avaliados antes de chamar a função.
  2. A ordem de avaliação dos referidos parâmetros não é garantida e pode ser compilador específico. Por isso, os objetos não se comportam da mesma maneira que eles fazem nos exemplos listados na pergunta / respostas anteriores.

Para mais informações, ter uma leitura do livro de Scott Meyers, ++ mais eficaz C . Felicidades!

Respondeu 07/08/2008 em 23:23
fonte usuário

votos
6

vb.net

if( x isNot Nothing AndAlso x.go()) then
  1. Avaliação é feita esquerda para a direita
  2. AndAlso operador garante que apenas se o lado esquerdo era verdade, será avaliado o lado direito (muito importante, pois IFX nada x.go irá falhar)

Você pode usar E em vez ofAndAlso em vb. caso em que o lado esquerdo fica avaliada em primeiro lugar, bem como, mas o lado direito vai ser avaliado independentemente do resultado.

Melhor Prática: Use sempre AndAlso, a menos que você tenha uma boa razão para que não o fizesse.


Ele foi perguntado em uma continuação porquê ou quando alguém iria usar E em vez de AndAlso (ou & vez de &&): Aqui está um exemplo:

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

Neste caso, eu quero o init X e Y. Y deve ser inicializado para que y.DoDance para ser capaz de executar. No entanto, na função init () Eu estou fazendo também algo extra, como a verificação de um soquete é aberto, e somente se isso funciona ok, para tanto , que eu deveria ir em frente e fazer o x.process (y).

Novamente, isso provavelmente não é necessário e não elegante em 99% dos casos, é por isso que eu disse que o padrão deve ser a utilização AndAlso .

Respondeu 07/08/2008 em 21:35
fonte usuário

votos
5

@shsteimer

O conceito modéstia está se referindo é a sobrecarga de operador. na declaração: ... Um é avaliada em primeiro lugar, se for avaliado como falso, B nunca é avaliada. O mesmo se aplica a

Isso não é a sobrecarga de operador. Sobrecarga de operadores é o termo dado para deixá-lo definir o comportamento personalizado para os operadores, tais como *, +, = e assim por diante.

Isso permitiria que você escrever sua própria classe 'Log', e em seguida, fazer

a = new Log(); // Log class overloads the + operator
a + "some string"; // Call the overloaded method - otherwise this wouldn't work because you can't normally add strings to objects.

Fazendo isso

a() || b() // be never runs if a is true

é realmente chamado Short Circuit Evaluation

Respondeu 07/08/2008 em 22:58
fonte usuário

votos
4

Algumas línguas têm situações interessantes onde as expressões são executadas em uma ordem diferente. Estou a pensar especificamente de Ruby, mas eu tenho certeza que eles emprestado de outro lugar (provavelmente Perl).

As expressões na lógica vai ficar à esquerda para a direita, mas, por exemplo:

puts message unless message.nil?

O acima irá avaliar "message.nil?" em primeiro lugar, em seguida, se for avaliado como falso (a menos que é como se a não ser que executa quando a condição for falsa, em vez de verdade), "coloca mensagem" será executado, que imprime o conteúdo da variável de mensagem na tela.

É uma espécie de uma forma interessante de estruturar o seu código às vezes ... Eu pessoalmente gosto de usá-lo para muito curtas 1 liners como o acima.

Editar:

Para torná-lo um pouco mais claro, o acima é o mesmo que:

unless message.nil?
  puts message
end
Respondeu 07/08/2008 em 21:54
fonte usuário

votos
4

Observe que há uma diferença entre && e & respeito de quanto de sua expressão é avaliada.

&& é conhecido como um boolean curto-circuito e, e, como observado por outros aqui, parar mais cedo se o resultado pode ser determinado antes de todas as sub-expressões são avaliadas.

E é conhecido como um operador bit a bit lógico e será sempre avaliar todas as sub-expressões.

Assim sendo:

if (a() && b())

Só vai chamar b se um retorno verdadeiro .

porém, isto:

if (a() & b())

Será sempre chamar tanto a e b , apesar do resultado de chamar uma é falsa e, portanto, conhecido por ser falsa , independentemente do resultado da chamada b .

Este mesmo diferença para o || e | operadores.

Respondeu 07/08/2008 em 21:52
fonte usuário

votos
4

ZombieSheep está morto-on. O único "pegadinha" que pode estar esperando é que isto só é verdade se você estiver usando o operador &&. Ao usar o operador &, ambas as expressões serão avaliadas a cada momento, independentemente se um ou ambos avaliar para falso.

if (amHungry & whiteCastleIsNearby)
{
   // The code will check if White Castle is nearby
   // even when I am not hungry
}

if (amHungry && whiteCastleIsNearby)
{
   // The code will only check if White Castle is nearby
   // when I am hungry
}
Respondeu 07/08/2008 em 21:45
fonte usuário

votos
2

O conceito modéstia está se referindo é a sobrecarga de operador. na declaração:

if( A && B){
    // do something
}

Um é avaliada em primeiro lugar, se for avaliado como falso, B nunca é avaliada. O mesmo se aplica a

if(A || B){
    //do something
}

Um é avaliada em primeiro lugar, se for avaliado como verdadeiro, B nunca é avaliada.

Este conceito, sobrecarga, aplica-se a (i pense) todos os idiomas estilo C, e muitos outros também.

Respondeu 07/08/2008 em 21:35
fonte usuário

votos
2

A da esquerda, em seguida, pára se ele é nulo.

Edit: Em vb.net que irá avaliar tanto e, possivelmente, lançar um erro, a menos que você use AndAlso

Respondeu 07/08/2008 em 21:31
fonte usuário

votos
1

Eu gosto de respostas de Orion. Vou acrescentar duas coisas:

  1. O da esquerda para a direita ainda se aplica primeiro
  2. O interior-to-exterior para garantir que todos os argumentos são resolvidos antes de chamar a função

Digamos que temos o seguinte exemplo:

a = Foo(5, GetSummary("Orion", GetAddress("Orion")),
           GetSummary("Chris", GetAddress("Chris")));

Aqui está a ordem de execução:

  1. GetAddress("Orion")
  2. GetSummary("Orion", ...)
  3. GetAddress("Chris")
  4. GetSummary("Chris", ...)
  5. Foo(...)
  6. atribui a a

Eu não posso falar sobre os requisitos legais de C # (embora eu testar um exemplo semelhante utilizando Mono antes de escrever este post), mas essa ordem é garantida em Java.

E apenas para a completude (uma vez que este é um segmento de linguagem agnóstico também), há linguagens como C e C ++, onde a ordem não é garantida a menos que haja um ponto de seqüência. Referências: 1 , 2 . Em resposta a uma pergunta do segmento, no entanto, &&e ||são pontos de sequência em C ++ (a não ser sobrecarregado; ver também excelente resposta de JO). Assim, alguns exemplos:

  • foo() && bar()
  • foo() & bar()

No &&caso, foo()é garantido que correr antes bar()(se o último for executado em todos), uma vez que &&é um ponto de sequência. No &caso, não existe tal garantia é feita (em C e C ++), e na verdade bar()pode ser executado antes foo(), ou vice-versa.

Respondeu 07/08/2008 em 23:33
fonte usuário

votos
1

Quando as coisas estão todos em linha, eles são executados da esquerda para a direita.

Quando as coisas são aninhados, eles são executados interna-to-exterior. Isto pode parecer confuso, pois geralmente o que é "mais íntimo" é sobre o lado direito da linha, por isso parece que está indo para trás ...

Por exemplo

a = Foo( 5, GetSummary( "Orion", GetAddress("Orion") ) );

As coisas acontecem assim:

  • Chamada GetAddresscom o literal"Orion"
  • Chamada GetSummarycom o literal "Orion"eo resultado daGetAddress
  • Chamada Foocom o literal 5eo resultado daGetSummary
  • Atribuir este valor para a
Respondeu 07/08/2008 em 23:02
fonte usuário

votos
1

O que é um bom exemplo de quando usar o operador bit a bit em vez do "boolean curto-circuito"?

Suponha que você tenha bandeiras, digamos, por atributos de arquivo. Suponha que você tenha definido lido como 4, ESCREVA como 2, e EXEC como 1. Em binário, isso é:

READ  0100  
WRITE 0010  
EXEC  0001

Cada bandeira tem um conjunto de bits, e cada um é único. Os operadores bit a bit permitem combinar esses sinalizadores:

flags = READ & EXEC; // value of flags is 0101
Respondeu 07/08/2008 em 22:51
fonte usuário

votos
1

Nopes, pelo menos, o compilador C # não funciona para trás (em qualquer && ou ||). É esquerda para a direita.

Respondeu 07/08/2008 em 22:00
fonte usuário

votos
0

A linguagem de programação D faz a avaliação da esquerda para a direita com curto-circuito e não permitir que a sobrecarga do &&e '||' operadores.

Respondeu 14/04/2010 em 23:49
fonte usuário

votos
0

@csmba :

Ele foi perguntado em uma continuação porquê ou quando alguém iria usar E em vez de AndAlso (ou & vez de &&): Aqui está um exemplo:

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

Neste caso, eu quero o init X e Y. Y deve ser inicializado para que y.DoDance para ser capaz de executar. No entanto, na função init () Eu estou fazendo também algo extra, como a verificação de um soquete é aberto, e somente se isso funciona ok, para ambos, eu deveria ir em frente e fazer o x.process (y).

Eu acredito que este é bastante confuso. Embora o seu exemplo funciona, não é o caso típico para o uso And(e eu provavelmente iria escrever isso de forma diferente para torná-lo mais claro). And( &Na maioria das outras línguas) é realmente o bit a bit e operação. Você poderia usá-lo para calcular operações de bit, por exemplo a exclusão de um pouco de bandeira ou mascarar e testar flags:

Dim x As Formatting = Formatting.Bold Or Formatting.Italic
If (x And Formatting.Italic) = Formatting.Italic Then
    MsgBox("The text will be set in italic.")
End If
Respondeu 20/08/2008 em 08:35
fonte usuário

votos
0

Você usa e quando você quer especificamente para avaliar todas as sub-expressões, provavelmente porque eles têm efeitos colaterais que você quer, mesmo que o resultado final será falsa e, portanto, não executar o seu então parte do seu caso -Declaração.

Note-se que & e | opera para ambas as máscaras de bit a bit e valores booleanos e não é apenas para operações bit a bit. Eles são chamados bit a bit, mas eles são definidos para ambos inteiros e tipos de dados booleanos em C #.

Respondeu 07/08/2008 em 23:01
fonte usuário

votos
0

Ouvi em algum lugar que compiladores trabalhar para trás, mas tenho certeza como isso é verdade.

Respondeu 07/08/2008 em 21:34
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more