Давайте сначала рассмотрим, что есть, как вы говорите, два возможных значения -1
и 0
. Есть вопрос, что следует делать, если 42
попадает туда; возможно ли это (вы правы в своем заявлении) или просто о возможном (значение действует как вариант_bool, в котором -1
является нормальным истинным значением, но все ненулевые должны рассматриваться как истинные), это стоит рассмотреть в любом случае. И имеет смысл лечить 42
так же, как мы лечим -1
; то есть имеет смысл рассматривать все ненулевые как одно и то же.
И даже если нет абсолютно никакого другого возможного ненулевого значения, чем -1
, он по-прежнему обобщает на «test is non-zero», который является очень распространенным случаем в другом месте, поэтому имеет смысл считать, что «тест ненулевой "случай. Это особенно важно, если компилятор не знает, что -1
- единственное возможное ненулевое значение (очень вероятно).
Теперь возникает вопрос о том, нужно ли напрямую связываться с значением (с brfalse
, brtrue
и т. Д.) Или выполнить логическую операцию, а затем развернуть результат. Как правило, как C# и VB.NET компиляторов будет производить логическое значение, а затем разветвляются на том, что в отладочной версии:
Простой код:
public void TestBool(bool x)
{
if(x)
throw new ArgumentOutOfRangeException();
}
Debug CIL:
nop
ldarg.1
ldc.i4.0
ceq
stloc.0
ldloc.0
brtrue.s NoError
newobj instance void [mscorlib]System.ArgumentOutOfRangeException::.ctor()
throw
NoError:
ret
релиз CIL :
ldarg.1
brfalse.s NoError
newobj instance void [mscorlib]System.ArgumentOutOfRangeException::.ctor()
throw
NoError:
ret
Дополнительные шаги по существу делают x == true
до doi ng отладка ветвящихся средств. Подобные эффекты иногда встречаются в коде выпуска, хотя и реже.
Итак, по этой причине мы проводим сравнение перед веткой в вашем коде, а не только с веткой.
Теперь возникает другой вопрос: следует ли нам проверять, что значение равно нулю или проверить, что значение не равно нулю; либо эквивалентно много, как:
if(x)
DoSomething();
И
if(!x)
{
}
else
DoSomething();
эквивалентны.
По этой причине ceq
может быть использован, с последующим разветвлением, подходящим для случая, когда item.Found
как 0
. Но это, если что-то более разумно использовать cne
с последующим разветвлением, подходящим для случая, когда item.Found
не является 0
.
Но нет такой инструкции CIL, как cne
, или что-либо, что сравнимо проверяет, если что-то не равно. Обычно для выполнения «проверки не равно» мы делаем последовательность ceq
, ldc.i4.0
, ceq
; проверьте, что два значения равны, а затем проверьте, что результат этой проверки является ложным.
К счастью, в общем случае, что мы проверяем, что-то не равно это 0
нам не нужен, потому что cne
cgt.un
логически эквивалентен в этом случае гипотетического cne
. Это делает cgt.un
очевидным выбором, если мы хотим проверить, что что-то не равно нулю.
И, следовательно, в то время как IYO «никто с разумным разумом делает различие между« -1 »и« 0 »таким образом,« это очень разумный способ действительно проверить ненулевое значение вообще. И действительно, cgt.un
часто появляется как просто такой ненулевой тест.
И связанный с этим: какой исходный исходный код наиболее вероятно?
If item.Found Then
'More stuff
End If
Что эквивалентно C#
if(item.Found != 0)
{
//More stuff
}
Вы уверены, что тип item.Found был ИНТ и не UINT в исходном коде? Просто дважды проверяйте, так как для меня непонятно, есть ли у вас доступ к исходному источнику или нет. –
Почти наверняка исходным кодом был эквивалент VB 'if (item.Found)' where' Found' был преобразован из Boolean. Вы просите рефлектора показать код VB, как если бы это был код C#, который, конечно же, может вызвать странные ситуации. Что вы получите, если указате рефлектору, чтобы показать его как код VB? (Помните, что VB представляет собой Boolean как 0 или -1 при преобразовании в числовые типы) –
@MatthewWatson Да, я пробовал - если я покажу его как VB.Net, ничего не изменится. Тем не менее, хотя Reflector делает приличную работу с C#, это не особенно хорошо с такими конструкциями. Тем не менее, то, что вы говорите, интересно - зачем вы компилируете это как 'cgt.un'? – atlaste