Pergunta

Em C#, (e sinta-se livre para responder por outras línguas), o que faz avaliar o tempo de execução de uma instrução de lógica?

Exemplo:

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

Que a declaração é o tempo de execução, primeiramente, avaliar -

myDt != null

ou:

myDt.Rows.Count > 0

?

Há um tempo quando o compilador iria avaliar a instrução de trás para frente?Talvez, quando um operador "OU" está envolvido?


e é conhecida como uma lógica operador bit a bit e sempre vai avaliar todas as sub-expressões

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

Foi útil?

Solução

C# :Da esquerda para a direita, e o processamento pára, se uma não-correspondência (avalia para false) é encontrado.

Outras dicas

"C# :Da esquerda para a direita, e o processamento pára se uma correspondência (avalia para true) é encontrado."

Ovelha zumbi é errado, não é suficiente representante para votar nele.

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

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

No caso de || a avaliação deixa de se uma VERDADEIRA é encontrada.

Eu sei que essa pergunta já foi respondida, mas eu gostaria de jogar em outro pedaço de informação que está relacionado com o tema.

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

  1. Ele quebra o preguiçoso mecanismo de avaliação, porque a sobrecarga é uma função que tem de ser invocada, 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.Portanto, os objetos não se comportam da mesma maneira como nos exemplos citados na pergunta/respostas anteriores.

Para mais informações, tenho uma leitura de Scott Meyers livro Mais Eficaz Do C++.Saúde!

vb.net

if( x isNot Nothing AndAlso x.go()) then
  1. A avaliação é feita da esquerda para a direita
  2. Loorders.tables.count o operador torna-se de que somente se, o lado esquerdo era VERDADEIRO, o lado direito será avaliado (muito importante, uma vez que o ifx é nada x.vá irá falhar)

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

Melhores Práticas:Use sempre Loorders.tables.count, a menos que você tenha uma razão muito boa por que não para.


Ele foi perguntado em uma continuação por que ou quando alguém iria usar E, em vez de Loorders.tables.count (ou & em vez de &&): Aqui está um exemplo:

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

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

Novamente, isso provavelmente não é necessária e não é elegante em 99% dos casos, é por isso que eu disse que o padrão deve ser para uso Loorders.tables.count.

@shsteimer

O conceito de modéstia está se referindo é o operador de sobrecarga.na declaração:...Uma é avaliada primeiro, se ele for avaliada como false, B nunca é avaliada.O mesmo se aplica para

Que não sobrecarregar do operador.Operador de sobrecarga é o termo dado para permitir definir personalizado comportamento para os operadores, tais como:*, +, = e assim por diante.

Isso deixa você escrever o seu próprio 'Log' de classe 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

na verdade, é chamado Curto-Circuito Avaliação

ZombieSheep está morto-no.A única "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 avaliada como false.

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
}

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

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

e é conhecida como uma lógica operador bit a bit e sempre vai avaliar todas as sub-expressões.

Como tal:

if (a() && b())

Só chamar b se um retorna verdadeiro.

no entanto, este:

if (a() & b())

Sempre vai chamar um e b, mesmo que o resultado da chamada um é falsa e, portanto, conhecido por ser falso independentemente do resultado da chamada b.

Esta mesma diferença existe com a || e | operadores.

Alguns idiomas possuem interessante situações em que as expressões são executadas em uma ordem diferente.Estou pensando especificamente do Ruby, mas eu tenho certeza que eles tomaram emprestado de outro lugar (provavelmente Perl).

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

puts message unless message.nil?

Acima irá avaliar "mensagem.nil?" em primeiro lugar, em seguida, se ele for avaliada como false (a menos, é como se, exceto que ele é executado quando a condição é falsa em vez de true), "coloca a mensagem" irá executar, o que imprime o conteúdo da mensagem variável para a tela.

É um jeito interessante a estrutura de seu código, por vezes,...Eu, pessoalmente, gosto de usá-lo para muito curto forros 1 como o acima.

Editar:

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

unless message.nil?
  puts message
end

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

Editar:No vb.net ele irá avaliar tanto e, possivelmente, jogar um erro, a menos que você use Loorders.tables.count

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

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

Uma é avaliada primeiro, se ele for avaliada como false, B nunca é avaliada.O mesmo se aplica para

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

Uma é avaliada primeiro, se ele for avaliada como true, B nunca é avaliada.

Este conceito, sobrecarga, se aplica (eu acho) todas as linguagens de estilo C, e muitos outros também.

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

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

Quando as coisas estão aninhados, eles são executados interior para o exterior.Isso pode parecer confuso, como geralmente o que é "interno" é no lado direito da linha, de modo que parece que vai para trás...

Por exemplo

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

As coisas acontecem assim:

  • Chamada GetAddress com o literal "Orion"
  • Chamada GetSummary com o literal "Orion" e o resultado de GetAddress
  • Chamada Foo com o literal 5 e o resultado de GetSummary
  • Atribuir este valor a a

Eu gosto de Orion respostas.Vou acrescentar duas coisas:

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

Dizer 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 C#'s requisitos legais (apesar de eu testar um exemplo semelhante, usando o Mono, antes de escrever este post), mas esta ordem é garantida em Java.

E apenas para a completude (uma vez que esta é uma língua independente do segmento de bem), existem linguagens como C e C++, onde a ordem não é garantida, a menos que haja um ponto de seqüência.Referências: 1, 2.No atendimento do segmento questão, no entanto, && e || são seqüência de pontos em C++ (a menos sobrecarregado;veja também JO excelente resposta).Então, alguns exemplos:

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

No && caso, foo() é garantida a execução antes bar() (se este último é executado em todos), desde que && é um ponto de seqüência.No & caso, nenhuma garantia é feita (em C e C++), e de fato bar() pode executar antes de foo(), ou vice-versa.

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

Suponha que você tenha bandeiras, digamos, atributos de ficheiro.Suponha que você tenha definido a LEITURA como 4, ESCRITA como 2, e EXEC como 1.Em binário, que é:

READ  0100  
WRITE 0010  
EXEC  0001

Cada bandeira tem um conjunto de bits, e cada um é único.Os operadores bit a bit permite combinar essas bandeiras:

flags = READ & EXEC; // value of flags is 0101

Eu ouvi em algum lugar que compiladores trabalhar para trás, mas eu não tenho certeza o quão verdadeiro isso é.

Você usar e quando você deseja especificamente para avaliar todas as sub-expressões, provavelmente porque eles têm efeitos colaterais que você deseja, mesmo que o resultado final será falso e, assim, não executar a sua em seguida, parte de seu se-instrução.

Note que & e | opera para tanto bit a bit máscaras e valores booleanos e não é apenas para operações bit a bit.Eles são chamado bit a bit, mas eles são definidos para os dois inteiros e booleanos tipos de dados em C#.

@csmba:

Ele foi perguntado em uma continuação por que ou quando alguém iria usar E, em vez de Loorders.tables.count (ou & em vez de &&):Aqui está um exemplo:

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

Neste caso, eu quero init X e Y.Y deve ser inicializado para y.DoDance para ser capaz de executar.No entanto, no init() função que eu estou fazendo também alguns extras coisa como a verificação de um socket é aberto, e somente se, que funciona ok, para tanto, que eu deveria ir em frente e fazer o x.processo(y).

Eu acredito que isto é bastante confuso.Embora o seu exemplo funciona, não é o caso típico para o uso de And (e eu provavelmente iria escrever isso de forma diferente para torná-lo mais claro). And (& na maioria das outras línguas) é, na verdade, o bit a bit e operação.Você poderia usá-lo para calcular operações bit, por exemplo, a exclusão de um sinalizador de bits ou de mascaramento e testes bandeiras:

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

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top