Я искал информацию об операторах if с несколькими условиями, но не нашел ничего, что соответствует моему вопросу.
Мне было интересно, можете ли вы написать:
int n = 3
if (3 < n < 20)
{
//do something..
}
вместо того, чтобы делать:
if (n > 3 && n < 20)
{
//do something..
}
Первый оператор для меня не работает, хотя я думаю, что он должен, потому что он очень простой.
Может быть, кто-то может дать мне правильный синтаксис для этого, или, может быть, это вообще невозможно, и мне просто нужно использовать AND.
Что произойдет, если вы попробуете?
хорошо, спасибо, что подтвердили это.
@Malling для такого подтверждения, ваш компилятор даже быстрее, чем SO! ;)
@AdrianoRepetti Однако, честно говоря, причина, по которой это не работает, немного более неясна.
«Я думаю, так и должно быть, потому что это очень просто» Что заставляет вас так думать? Язык программирования не обязательно соответствует общему синтаксису, который вы можете представить себе в математике. У всех языков есть свой синтаксис, которому вы должны следовать. 3 < n < 20
обязательно соответствует нет любому из этих синтаксических правил.
@Sayse Он жалуется на то, что первый оператор <не может быть применен к операндам типа bool и int
@DavidG это ?!
@AdrianoRepetti Для новичка да.
@HimBromBeere, я знаю, я знаю, что это может означать многое, когда язык должен его компилировать, но я просто писал это так в большинстве математических программ, поэтому я подумал, что, возможно, C# тоже может это понять :)
@DavidG - правда!
И теперь вы знаете, что это не так. Так о чем на самом деле этот вопрос?
@Malling, если вы искали "почему", то мне определенно придется отменить свой голос против. Сам по себе это неплохой вопрос. Кстати, некоторые другие (не математические) языки позволяют вам писать так (например, Python), но причина, по которой это работает, может быть довольно разной для каждого языка.
@AdrianoRepetti на самом деле это был вопрос «почему», потому что я не могу заставить его работать и не понимаю почему :)
Чтобы объяснить, почему это недействительно:
if (3 < n < 20)
Можно переписать как:
if ((3 < n) < 20)
Теперь результат 3 < n
будет логичным.
Итак, в основном вы получите:
if (true/false < 20)
Что недопустимо в C#.
О да, это объясняет ошибку, которую я получаю, говоря, что он не может преобразовать из bool в int. Спасибо за ваше объяснение!
Я отмечаю это как решение, потому что оно объясняет, почему я не могу этого сделать!
Это недопустимо, потому что разработчики языка не разрешили синтаксис в вопросе. Они мог разрешили это, если хотели.
Привет @ LasseVågsætherKarlsen: это то, что я хотел сказать, прямо заявив, что это вещь C#: "что недопустимо в C#". Я согласен с тем, что мой ответ является предметом хороших дискуссий, но мое основное намерение здесь состояло в том, чтобы позволить OP увидеть, «почему» (на данный момент) он недействителен, объяснить ошибку и, главным образом, чтобы он / она мог обнаружить подобные случаи в будущем . Тем не менее, вы правы, это выбор дизайнеров, и многие другие языки примут такой синтаксис.
Обычно то, что вы хотите делать, невозможно.
но в вашей логике, если вы хотите выполнить однострочную логику, вы можете использовать тернарный оператор.
для напр. вам нужно присвоить значение n переменной result
, иначе по умолчанию должно быть 0.
int result = n > 3 ? (n < 20 ? n : 0) : 0
это эквивалентно
int result = 0;
if (n > 3 && n < 20)
{
result = n;
}
Ответ Стефана объясняет, почему это невозможно.
Но вот обходной путь, если вы не хотите каждый раз писать эти надоедливые явные условия &&
- вы можете создать метод расширения:
public static class IComparableExtensions
{
public static bool Between<T>(this T self, T low, T high) where T : IComparable
{
return self.CompareTo(low) > 0 && self.CompareTo(high) < 0;
}
}
И используйте это так:
int n = 5;
if (n.Between(3, 20))
{
// do your stuff here
}
Однако обратите внимание, что это может сбивать с толку - поскольку Between
не указывает, является ли сравнение включающим, исключающим или включающим только в одном направлении - поэтому, если вы сравниваете, скажем, 20.Between(10, 20)
- должно ли оно возвращать истину или ложь?
Для лучшего подхода потребуется добавить в метод еще одну переменную, чтобы указать, что:
[Flags]
public enum CompareMode
{
Exclusive = 0,
IncludeLow = 1,
IncludeHigh = 2,
Inclusive = IncludeLow | IncludeHigh
}
public static class IComparableExtensions
{
public static bool Between<T>(this T self, T low, T high, CompareMode mode) where T : IComparable
{
var compareLow = (mode & CompareMode.IncludeLow) == CompareMode.IncludeLow ? 0 : 1;
var compareHigh = (mode & CompareMode.IncludeHigh) == CompareMode.IncludeHigh ? 0 : -1;
return self.CompareTo(low) >= compareLow && self.CompareTo(high) <= compareHigh;
}
}
Теперь вы используете это так:
if (n.Between(3, 20, CompareMode.Exclusive))
{
// do your stuff here
}
Вы можете увидеть живую демонстрацию на rextester.
Таким образом, другой человек, читающий этот код (или даже вы, через 6 месяцев), сразу же узнает, без необходимости заглядывать внутрь метода расширения Between
, если between является включающим, исключающим или чем-то еще.
Разве вы не вызываете метод, чтобы сделать то же самое, что OP не хотел делать в первую очередь?
@Amit Да, но суть метода расширения состоит в том, чтобы исключить необходимость каждый раз писать явное условие. Это просто ярлык ...
@Amit Я отредактировал свой ответ, чтобы лучше это объяснить. Благодаря вашим комментариям мой ответ стал лучше, так что спасибо!
Нет, нужно использовать второй синтаксис, первая версия работать не будет.