C # логики порядка и поведение компилятора

голоса
14

В C #, (и не стесняйтесь ответить на других языках), в каком порядке это среда выполнения оценки логического утверждения?

Пример:

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

Какое утверждение делает выполнение оценки первым -

myDt != null

или:

myDt.Rows.Count > 0

?

Есть ли время, когда компилятор будет когда-либо оценивать заявление в обратном направлении? Может быть, когда оператор «ИЛИ» участвует?


И известен как логический оператор побитового и всегда будет оценивать все подвыражения

Что такое хороший пример того, когда использовать оператор побитового вместо «короткозамкнутой булева»?

Задан 07/08/2008 в 21:30
источник пользователем
На других языках...                            


18 ответов

голоса
16

C #: Слева направо, и обработка прекращается, если не-матч (оценивается как ложное) найдено.

Ответил 07/08/2008 в 21:33
источник пользователем

голоса
9

«C #: слева направо, и обработка прекращается, если матч (принимает значение истина) будет найден.»

Зомби овцы не так, не хватает респ вниз голос его.

Речь идет об операторе &&, а не || оператор.

В случае && оценки остановится, если FALSE найден.

В случае || оценка останавливается, если TRUE, будет найден.

Ответил 08/08/2008 в 07:51
источник пользователем

голоса
8

Я понимаю, что этот вопрос уже был дан ответ, но я хотел бы, чтобы бросить в другой бит информации, которая связана с этой темой.

В языках, как C ++, где вы можете перегрузить поведение && и || операторы, настоятельно рекомендуется не делать этого . Это происходит потому , что при перегрузке этого поведения, вы в конечном итоге вынудив оценку обоего сторон операции. Это делает две вещи:

  1. Он ломает ленивый механизм оценки, поскольку перегрузка является функцией, которая должна быть вызвана, и, следовательно, оба параметра вычисляется перед вызовом функции.
  2. Порядок оценки указанных параметров не гарантируется и может быть компилятор специфичны. Следовательно, объекты не будут вести себя таким же образом, как и в примерах, приведенных в вопрос / предыдущих ответов.

Для получения дополнительной информации, есть читать книги Скотт Мейерс, более эффективном C ++ . Ура!

Ответил 07/08/2008 в 23:23
источник пользователем

голоса
6

vb.net

if( x isNot Nothing AndAlso x.go()) then
  1. Оценка делается слева направо
  2. AndAlso оператор гарантирует , что только тогда , когда левая сторона была TRUE, правая сторона будет оцениваться (очень важно, так как IFX ничего x.go разобьет)

Вы можете использовать и вместо ofAndAlso в VB. в этом случае левая сторона получает оценку первым , как хорошо, но правая сторона будет получить оценку , независимо от результата.

Лучшая практика: Всегда используйте AndAlso, если у вас есть очень веские причины, почему не делать этого.


Был задан вопрос , в последующем наблюдении , почему и когда бы кто - нибудь использовать и вместо AndAlso (или & вместо &&): Вот пример:

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

В этом случае, я хочу , чтобы инициализировать как X и Y. Y должен быть инициализирован для того , чтобы y.DoDance , чтобы быть в состоянии выполнить. Однако, в функции инициализации () Я делаю также некоторые дополнительные вещи , как проверка сокет открыт, и только если это работает нормально, для обоих , я должен идти вперед и делать x.process (у).

Опять же , это, вероятно , не нужно и не шикарно в 99% случаях, поэтому я сказал , что по умолчанию должно быть использовать AndAlso .

Ответил 07/08/2008 в 21:35
источник пользователем

голоса
5

@shsteimer

Понятие скромности имеет в виду оператор перегрузки. в заявлении: ... А сначала вычисляется, если она принимает значение ложь, B никогда не оценивали. То же самое относится и к

Это не перегрузка операторов. Перегрузка операторов это термин для позволяя определить пользовательское поведение для операторов, таких как *, +, = и так далее.

Это позволит вам написать свой собственный класс «Log», а затем сделать

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.

Делая это

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

на самом деле называется короткого замыкания оценка

Ответил 07/08/2008 в 22:58
источник пользователем

голоса
4

Некоторые языки имеют интересные ситуации, в которых выражения выполняются в другом порядке. Я специально думать о Ruby, но я уверен, что они заимствовали из других (возможно, Perl).

Выражения в логике останется слева направо, но, к примеру:

puts message unless message.nil?

Выше оценит «message.nil?» первым, а затем, если она принимает значение лжи (если не нравится, если только она выполняется, когда условие ложно, а не так), «помещает сообщение» исполнит, который печатает содержимое переменных сообщений на экран.

Это своего рода интересного способа структурирования коды иногда ... Я лично хотел бы использовать его для очень коротких 1 вкладышей, как выше.

Редактировать:

Для того, чтобы сделать его немного яснее, выше, является такой же, как:

unless message.nil?
  puts message
end
Ответил 07/08/2008 в 21:54
источник пользователем

голоса
4

Обратите внимание, что есть разница между && и & относительно того, как много из вашего выражения вычисляются.

&& известен как короткое замыкание логическое И, и, как отмечают другие здесь, остановить раньше, если результат может быть определен, прежде чем все подвыражения оцениваются.

И известен как логический оператор побитового и всегда будет оценивать все подвыражения.

Как таковой:

if (a() && b())

Будет вызывать только б , если а возвращает истинный .

Однако, это:

if (a() & b())

Всегда будут называть как а , и Ь , даже если результат вызова является ложным и , таким образом , как известно, ложь , независимо от результата вызова б .

Это такая же разница существует для || и | операторы.

Ответил 07/08/2008 в 21:52
источник пользователем

голоса
4

ZombieSheep мертв-на. Единственный «глюк», которые могли бы ждать, что это только справедливо, если вы используете оператор &&. При использовании и оператора, оба выражения будут оцениваться каждый раз, независимо от того, один или оба оценить ложь.

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
}
Ответил 07/08/2008 в 21:45
источник пользователем

голоса
2

Понятие скромности имеет в виду оператор перегрузки. в заявлении:

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

А сначала вычисляется, если она принимает значение ложь, B никогда не оценивали. То же самое относится и к

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

А сначала вычисляется, если оно истинно, B никогда не оценивали.

Эта концепция, перегрузка, относится к (я думаю) все языки типа C, и многие другие, а также.

Ответил 07/08/2008 в 21:35
источник пользователем

голоса
2

Левая, затем останавливается, если она равна нулю.

Edit: В vb.net он будет оценивать как и, возможно, выдаст ошибку, если вы не используете AndAlso

Ответил 07/08/2008 в 21:31
источник пользователем

голоса
1

Мне нравится ответ Ориона. Я добавлю две вещи:

  1. Влево-вправо еще применяется первым
  2. Внутреннего к внешнему, чтобы гарантировать, что все аргументы будут решены перед вызовом функции

Скажем, у нас есть следующий пример:

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

Вот порядок исполнения:

  1. GetAddress("Orion")
  2. GetSummary("Orion", ...)
  3. GetAddress("Chris")
  4. GetSummary("Chris", ...)
  5. Foo(...)
  6. Назначает на a

Я не могу говорить о правовых требованиях, C # 's (хотя я проверить аналогичный пример с использованием Mono, прежде чем писать этот пост), но этот порядок гарантирован в Java.

И только для полноты (так как это зависит от языка нить, а), есть такие языки , как C и C ++, где порядок не гарантируется , если не существует точка последовательности. Список литературы: 1 , 2 . При ответе на вопрос Нить, однако, &&и ||есть последовательность точек в C ++ (если не перегружен, также видим отличный ответ OJ в). Так что некоторые примеры:

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

В &&случае, foo()гарантируется скороходов bar()(если последний работает вообще), так как &&точка последовательности. В &случае такой гарантии не производится (в C и C ++), и в самом деле bar()может работать до того foo(), или наоборот.

Ответил 07/08/2008 в 23:33
источник пользователем

голоса
1

Когда вещи все в линию, они выполняются слева направо.

Когда дела вложены, они выполнены внутренние к внешнему. Это может показаться странным, как правило, что «внутренний» находится на правой стороне линии, так что кажется, что это происходит в обратном направлении ...

Например

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

Вещи случаются, как это:

  • Вызов GetAddressс буквальным"Orion"
  • Вызов GetSummaryс буквальным "Orion"и результатомGetAddress
  • Вызов Fooс буквальным 5и результатомGetSummary
  • Присвоить это значение a
Ответил 07/08/2008 в 23:02
источник пользователем

голоса
1

Что такое хороший пример того, когда использовать оператор побитового вместо «короткозамкнутой булева»?

Предположим, у вас есть флаги, скажем, для атрибутов файлов. Предположим, что вы определили READ как 4, ПИШИТЕ как 2, и EXEC как 1. В двоичной, это:

READ  0100  
WRITE 0010  
EXEC  0001

Каждый флаг имеет один набор бит, и каждый из них уникален. Битовые операторы позволяют объединить эти флаги:

flags = READ & EXEC; // value of flags is 0101
Ответил 07/08/2008 в 22:51
источник пользователем

голоса
1

Nopes, по крайней мере, компилятор С # не работает в обратном направлении (в любом && или ||). Это слева направо.

Ответил 07/08/2008 в 22:00
источник пользователем

голоса
0

Язык программирования D ли делать влево-вправо оценку с коротким замыканием и не допускать перегрузки &&и «||» операторы.

Ответил 14/04/2010 в 23:49
источник пользователем

голоса
0

@csmba :

Был задан вопрос, в последующем наблюдении, почему и когда бы кто-нибудь использовать и вместо AndAlso (или & вместо &&): Вот пример:

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

В этом случае, я хочу, чтобы инициализировать как X и Y. Y должен быть инициализирован для того, чтобы y.DoDance, чтобы быть в состоянии выполнить. Однако, в функции инициализации () Я делаю также некоторые дополнительные вещи, как проверка сокет открыт, и только если это работает нормально, для обоих, я должен идти вперед и делать x.process (у).

Я считаю , что это довольно запутанной. Несмотря на то, что ваш пример работает, это не типичный случай для использования And(и я бы , вероятно , написать это по- другому , чтобы сделать его более четким). And( &В большинстве других языков) на самом деле поразрядная и операция. Вы могли бы использовать его для вычисления битовых операций, например , удаления бита флага или маскировки и тестирования флагов:

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
Ответил 20/08/2008 в 08:35
источник пользователем

голоса
0

Вы можете использовать и когда вы специально хотите , чтобы оценить все подвыражения, скорее всего , потому что они имеют побочные эффекты , которые вы хотите, даже если конечный результат будет ложным , и , таким образом , не выполнить свое то часть вашего если -statement.

Обратите внимание , что & и | работает как для поразрядных масок и логических значений и не только для битовых операций. Они называются побитовое, но они определяются как для целых чисел и логических типов данных в C #.

Ответил 07/08/2008 в 23:01
источник пользователем

голоса
0

Я где-то слышал, что компиляторы работают в обратном направлении, но я не уверен, насколько это верно.

Ответил 07/08/2008 в 21:34
источник пользователем

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