В C# (и не стесняйтесь отвечать для других языков), в каком порядке среда выполнения оценивает логическое утверждение?
Пример:
DataTable myDt = new DataTable();
if (myDt != null && myDt.Rows.Count > 0)
{
//do some stuff with myDt
}
Какое утверждение среда выполнения оценивает первым -
myDt != null
или:
myDt.Rows.Count > 0
?
Существует ли ситуация, когда компилятор оценивает утверждение в обратном порядке? Возможно, когда задействован оператор "ИЛИ"?
& известен как логический побитовый оператор и всегда будет оценивать все подвыражения
Какой хороший пример использования побитового оператора вместо "короткозамкнутого булева"?
C# : Слева направо, и обработка останавливается, если найдено несовпадение (оценивается как false).
на "языке C# : слева направо, и обработка прекращается, если матч (значение true) не найдено.&и quot;
Овца-зомби, овца-это неправильно, не хватает рэп, чтобы проголосовать его вниз.
Вопрос о &&усилителя; оператор, не оператор||.
В случае с &амп;&амп; оценка будет остановить, если память не найдено.
В случае || оценка останавливается, если истинный не найдено.
Я понимаю, что это вопрос уже отвечали, но я'd, как, чтобы скинуть еще немного информации, которая имеет отношение к теме.
В языках, таких как C++, где можно реально перегрузить поведение на && и || операторы, настоятельно рекомендуется не делай этого. Это потому, что когда вы перегружаете такое поведение, вы в конечном итоге заставляя оценке обеих сторон операции. Это делает две вещи:
Подробнее прочитать о Скотт Мейерс' книги более эффективный с++. Ура!
vb.net
if( x isNot Nothing AndAlso x.go()) then
Вы можете использовать и вместо ofAndAlso в VB. в этом случае левая сторона получает оценку первой, но правая сторона будет Вам оцениваться независимо от результата.
Рекомендация: всегда использовать andalso, если у вас есть очень хорошая причина, почему нет.
Было предложено в последующем, почему и когда бы кто-нибудь использовать и вместо атакже (или & вместо &&усилителя;): Вот пример:
if ( x.init() And y.init()) then
x.process(y)
end
y.doDance()
В данном случае, я хочу инит обоих X и Y. y должен быть инициализирован для того, Для у.DoDance чтобы быть в состоянии выполнить. Однако, в функции init() я делаю также некоторые дополнительные вещи, как проверка сокет открыт, и только если это работает ОК, за и, я должен идти вперед и делать х.процесс(г).
Опять-таки, это, наверное, не нужен и не шикарно в 99% случаев, именно поэтому я сказал, что по умолчанию следует использовать атакже.
@shsteimer &ГТ; понятие скромность имею в виду перегрузку операторов. в заявлении: &ГТ; ... &ГТ; оценивается первым, если его значение равно false, б никогда не оценивали. То же самое относится к
Что's не перегружать оператора. Перегрузка операторов-это срок, отведенный для позволяет определять нестандартное поведение для операторы, такие как *, +, = и так далее.
Это позволит вам написать свой собственный 'журнал' класс, а потом делать
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
на самом деле называется быструю оценку
ZombieSheep мертв-на. Единственный на "попался", Что может быть ожидания, что это только верно, если вы используете &амп;&амп; оператор. При использовании &амп; оператор, оба выражения будет выполняться каждый раз, независимо от того, если один или оба 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
}
Обратите внимание, что есть разница между &усилитель;& и & о том, сколько из вашего выражения.
усилитель&;&амп; известен как короткое замыкание логическое И, и, как отметили другие здесь, останавливаться рано, если результат можно определить до всех суб-выражений.
&амп; известен как оператор побитового и всегда будет оценивать все подвыражения.
В качестве таких:
if (a() && b())
Будет вызывать только б если в возвращения правда.
однако, это:
if (a() & b())
Всегда называйте как А и б, хотя результат вызова * это ложь и так известно, что ложь вне зависимости от результата вызова б*.
Такая же разница существует для || и | операторов.
Некоторые языки имеют интересные ситуации, когда выражения выполняются в другом порядке. Я думаю о Руби, но я'м уверены, что они заимствовали его у других (вероятно, на Perl).
Выражения в логике останется слева направо, но например:
puts message unless message.nil?
Выше будет оценивать и quot;сообщение.шь?" первый, то если его значение равно false (если это нравится, если только это выполняется, если условие имеет значение false вместо true), то "ставит сообщение" и будет исполнять, которая печатает содержимое сообщения переменной на экран.
Это'ы вроде интересный способ структурировать ваш код иногда... я лично хотел бы использовать его для очень коротких 1 вкладыши как выше.
Редактировать:
Чтобы сделать его немного яснее, выше такое же, как:
unless message.nil?
puts message
end
Понятие скромность имею в виду перегрузку операторов. в заявлении:
if( A && B){
// do something
}
Оценивается первым, если его значение равно false, б никогда не оценивали. То же самое относится к
if(A || B){
//do something
}
Оценивается во-первых, если он возвращает true, б никогда не оценивали.
Эта концепция, перегрузки, относится к (как мне кажется) все на языках C стиль, а также многие другие.
&ГТ;что это хороший пример, когда следует использовать оператор побитового а не от "короткое замыкание логическое и quot;?
Предположим, у вас есть флаги, говорить на атрибуты файла. Предположим, что вы'вэ определено читать в 4, писать как 2, и exec как 1. В двоичном, что'ы:
READ 0100
WRITE 0010
EXEC 0001
Каждый флаг имеет один бит, и каждый из них уникален. Побитовые операторы позволяют сочетать эти флаги:
flags = READ & EXEC; // value of flags is 0101
Когда все в он-лайн, они'выполняются слева направо.
Когда что-то вложены, они'вновь выполнено внутреннее-для-внешнего. Это может показаться запутанным, как обычно, что'ы с "внутренней" это на правой стороне, так кажется, что это's идя задом наперед...
Например
a = Foo( 5, GetSummary( "Orion", GetAddress("Orion") ) );
Бывает такой:
GetAddress с литералом
"Орион"`GetSummary с литералом
"Орион"и в результате
GetAddress`Фу
с литералом 5
и в результате GetSummary
Мне нравится Орион'ответы. Я'Лл добавить две вещи:
У нас есть следующий пример:
a = Foo(5, GetSummary("Orion", GetAddress("Orion")),
GetSummary("Chris", GetAddress("Chris")));
Здесь'ь порядок выполнения:
GetAddress("Орион")
GetSummary("Орион", ...)
GetAddress (на"Крис" - а)
GetSummary (на"Крис" у, ...)
Foo(...)
а
Я могу'т говорить о c#'правовые требования (хотя я делала тест аналогичный пример с использованием моно прежде чем писать этот пост), но этот заказ будет гарантированно в Java.
И просто для полноты картины (так как это язык-агностик нить так же), есть языки, как C и C++, где порядок не гарантируется, если есть точка следования. Ссылки: 1, [2](http://www.parashift.com/c++-чаво-лайт/разное-технические вопросы.сообщение: чаво-39.16). Отвечая на теме'однако вопрос,, &&усилителя; и
| | ` являются точками последовательности в C++ (если не перегружены; Также см. ОЖ'с выбором ответа). Таким образом, некоторые примеры:
Foo() &&усилителя; бар()
Foo() & бар()
В &&усилителя;
случае, Foo()
является гарантированный запуск до бар()(если последняя не будет работать вообще), так как
&&усилителя;точка следования. В
&амп;случае, нет таких гарантий (в C и C++), да и вообще бар()
может выполняться с Foo()
, или наоборот.
Д язык программирования делает слева-направо оценки закоротить и не'Т разрешить перегрузку `&&усилителя; и '||' операторов.
Я где-то слышал, что компиляторы работают в обратном направлении, но я не уверен, насколько это правда.
Это было предложено в последующем, почему и когда бы кто-нибудь использовать и вместо атакже (или & вместо &&усилителя;): вот пример:
&ГТ; если ( Х.метод init() и y.метод init()) тогда &ГТ; х.процесс(г)
В конце &ГТ; г.doDance()
В данном случае, я хочу инит обоих X и Y. y должен быть инициализирован для того, Для у.DoDance чтобы быть в состоянии выполнить. Однако, в функции init() я делаю также некоторые дополнительные вещи, как проверка сокет открыт, и только если это получается хорошо, как я должен идти вперед и делать х.процесс(г).
Я считаю, что это довольно запутанным. Хотя ваш пример работает, это's не типичный случай для с использованием <код>И< код&ГТ; (и я бы, наверное, написать это по-другому, чтобы было понятнее). в <код>И< код&ГТ; (в<код&ГТ;&ампер; на< код> В большинстве других языков) на самом деле побитового и эксплуатации. Вы бы использовать его для расчета разрядных операций, например при удалении флаг или маскирования и тестирование флаги:
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
Вы используете &амп; когда вы специально хотите оценить все подвыражения, скорее всего, потому что они имеют побочные эффекты, которые вы хотите, даже если конечный результат будет ложь и, следовательно, не выполнить свой тогда часть если-заявление.
Обратите внимание, что & и | действует для побитовых масок и логических значений и не только для побитовых операций. Они'ре Н побитовое, но они определены для целых чисел и булевых типов данных в C#.