Оператор if с несколькими условиями вместо использования AND

Я искал информацию об операторах if с несколькими условиями, но не нашел ничего, что соответствует моему вопросу.

Мне было интересно, можете ли вы написать:

int n = 3
if (3 < n < 20)
{
   //do something..
}

вместо того, чтобы делать:

if (n > 3 && n < 20)
{
   //do something..
}

Первый оператор для меня не работает, хотя я думаю, что он должен, потому что он очень простой.

Может быть, кто-то может дать мне правильный синтаксис для этого, или, может быть, это вообще невозможно, и мне просто нужно использовать AND.

Нет, нужно использовать второй синтаксис, первая версия работать не будет.

DavidG 01.05.2018 11:36

Что произойдет, если вы попробуете?

Sayse 01.05.2018 11:36

хорошо, спасибо, что подтвердили это.

Malling 01.05.2018 11:37

@Malling для такого подтверждения, ваш компилятор даже быстрее, чем SO! ;)

Adriano Repetti 01.05.2018 11:38

@AdrianoRepetti Однако, честно говоря, причина, по которой это не работает, немного более неясна.

DavidG 01.05.2018 11:38

«Я думаю, так и должно быть, потому что это очень просто» Что заставляет вас так думать? Язык программирования не обязательно соответствует общему синтаксису, который вы можете представить себе в математике. У всех языков есть свой синтаксис, которому вы должны следовать. 3 < n < 20 обязательно соответствует нет любому из этих синтаксических правил.

HimBromBeere 01.05.2018 11:38

@Sayse Он жалуется на то, что первый оператор <не может быть применен к операндам типа bool и int

Malling 01.05.2018 11:39

@DavidG это ?!

Adriano Repetti 01.05.2018 11:40

@AdrianoRepetti Для новичка да.

DavidG 01.05.2018 11:40

@HimBromBeere, я знаю, я знаю, что это может означать многое, когда язык должен его компилировать, но я просто писал это так в большинстве математических программ, поэтому я подумал, что, возможно, C# тоже может это понять :)

Malling 01.05.2018 11:40

@DavidG - правда!

Adriano Repetti 01.05.2018 11:41

И теперь вы знаете, что это не так. Так о чем на самом деле этот вопрос?

HimBromBeere 01.05.2018 11:42

@Malling, если вы искали "почему", то мне определенно придется отменить свой голос против. Сам по себе это неплохой вопрос. Кстати, некоторые другие (не математические) языки позволяют вам писать так (например, Python), но причина, по которой это работает, может быть довольно разной для каждого языка.

Adriano Repetti 01.05.2018 11:42

@AdrianoRepetti на самом деле это был вопрос «почему», потому что я не могу заставить его работать и не понимаю почему :)

Malling 01.05.2018 11:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
14
182
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Чтобы объяснить, почему это недействительно:

if (3 < n < 20)

Можно переписать как:

if ((3 < n) < 20)

Теперь результат 3 < n будет логичным.

Итак, в основном вы получите:

if (true/false < 20)

Что недопустимо в C#.

О да, это объясняет ошибку, которую я получаю, говоря, что он не может преобразовать из bool в int. Спасибо за ваше объяснение!

Malling 01.05.2018 11:43

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

Malling 01.05.2018 11:44

Это недопустимо, потому что разработчики языка не разрешили синтаксис в вопросе. Они мог разрешили это, если хотели.

Lasse V. Karlsen 01.05.2018 15:11

Привет @ LasseVågsætherKarlsen: это то, что я хотел сказать, прямо заявив, что это вещь C#: "что недопустимо в C#". Я согласен с тем, что мой ответ является предметом хороших дискуссий, но мое основное намерение здесь состояло в том, чтобы позволить OP увидеть, «почему» (на данный момент) он недействителен, объяснить ошибку и, главным образом, чтобы он / она мог обнаружить подобные случаи в будущем . Тем не менее, вы правы, это выбор дизайнеров, и многие другие языки примут такой синтаксис.

Stefan 01.05.2018 15:41

Обычно то, что вы хотите делать, невозможно.

но в вашей логике, если вы хотите выполнить однострочную логику, вы можете использовать тернарный оператор.

для напр. вам нужно присвоить значение 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 01.05.2018 11:46

@Amit Да, но суть метода расширения состоит в том, чтобы исключить необходимость каждый раз писать явное условие. Это просто ярлык ...

Zohar Peled 01.05.2018 11:47

@Amit Я отредактировал свой ответ, чтобы лучше это объяснить. Благодаря вашим комментариям мой ответ стал лучше, так что спасибо!

Zohar Peled 01.05.2018 11:49

Другие вопросы по теме