Подтвердить что ты не робот

Если утверждения, соответствующие нескольким значениям

Какой-нибудь более простой способ написать этот оператор if?

if (value==1 || value==2)

Например... в SQL вы можете сказать where value in (1,2) вместо where value=1 or value=2.

Я ищу что-то, что будет работать с любым базовым типом... string, int и т.д.

4b9b3361

Ответ 1

Как насчет:

if (new[] {1, 2}.Contains(value))

Это взломать хотя:)

Или, если вы не возражаете против создания собственного метода расширения, вы можете создать следующее:

public static bool In<T>(this T obj, params T[] args)
{
    return args.Contains(obj);
}

И вы можете использовать его следующим образом:

if (1.In(1, 2))

:)

Ответ 2

Более сложный путь:), который эмулирует SQL 'IN':

public static class Ext {    
    public static bool In<T>(this T t,params T[] values){
        foreach (T value in values) {
            if (t.Equals(value)) {
                return true;
            }
        }
        return false;
    }
}

if (value.In(1,2)) {
    // ...
}

Но идти стандартным способом, это более читаемо.

EDIT: лучшее решение, согласно предложению @Kobi:

public static class Ext {    
    public static bool In<T>(this T t,params T[] values){
        return values.Contains(t);
    }
}

Ответ 3

Это то, что вы ищете?

if (new int[] { 1, 2, 3, 4, 5 }.Contains(value))

Ответ 4

Если у вас есть Список, вы можете использовать .Contains(yourObject), если вы просто ищете его (например, где). В противном случае посмотрите на метод расширения Linq.Any().

Ответ 5

Используя Linq,

if(new int[] {1, 2}.Contains(value))

Но мне пришлось бы думать, что ваш оригинал, если быстрее.

Ответ 6

Альтернативно, и это даст вам большую гибкость, если тестирование для значений, отличных от 1 или 2 в будущем, заключается в использовании оператора switch

switch(value)
{
case 1:
case 2:
   return true;
default:
   return false
}

Ответ 7

Если вы много раз находите значение в фиксированном списке значений, используйте HashSet <T> , даже для HashSet, поскольку он хранит/выполняет поиск данных в двоичном дереве поиска.

HashSet<int> nums = new HashSet<int> { 1, 2, 3, 4, 5 };
// ....
if (nums.Contains(value))

Ответ 8

Как правило, нет.

Да, бывают случаи, когда список находится в Array или List, но это не общий случай.

Ответ 9

Использование методов расширения:

public static class ObjectExtension
{
    public static bool In(this object obj, params object[] objects)
    {
        if (objects == null || obj == null)
            return false;
        object found = objects.FirstOrDefault(o => o.GetType().Equals(obj.GetType()) && o.Equals(obj));
        return (found != null);
    }
}

Теперь вы можете сделать это:

string role= "Admin";
if (role.In("Admin", "Director"))
{ 
    ...
} 

Ответ 10

Легче субъективно, но, возможно, оператор switch будет проще? Вам не нужно повторять эту переменную, поэтому в строке может поместиться больше значений, а строка со многими сравнениями будет более разборчивой, чем другая, использующая оператор if.

Ответ 11

Такой метод расширения сделал бы это...

public static bool In<T>(this T item, params T[] items)
{
    return items.Contains(item);
}

Используйте его следующим образом:

Console.WriteLine(1.In(1,2,3));
Console.WriteLine("a".In("a", "b"));

Ответ 12

В vb.net или С# я ожидал бы, что самый быстрый общий подход для сравнения переменной с любым разумным количеством отдельно названных объектов (в отличие от, например, всех вещей в коллекции) будет состоять в том, чтобы просто сравнить каждый объект с сравнение и многое, что вы сделали. Конечно, возможно создать экземпляр коллекции и посмотреть, содержит ли он этот объект, и это может быть более выразительным, чем сравнение объекта со всеми элементами отдельно, но если вы не используете конструкцию, которую компилятор может явно распознать, такой код почти наверняка будет намного медленнее, чем просто делать отдельные сравнения. Я бы не стал беспокоиться о скорости, если код по своей природе будет работать не более нескольких сотен раз в секунду, но я бы опасался, что код будет перенаправлен на то, что работает гораздо чаще, чем первоначально предполагалось.

Альтернативный подход, если переменная является чем-то вроде типа перечисления, заключается в выборе значений перечисления power-of-two, позволяющих использовать битмаски. Если тип перечисления имеет 32 или менее допустимых значений (например, начиная с Harry = 1, Ron = 2, Hermione = 4, Ginny = 8, Neville = 16), можно хранить их в целых числах и проверять сразу несколько бит в одном ((if ((thisOne и (Harry | Ron | Neville | Beatrix))!= 0)/* Сделайте что-то */. Это позволит быстро скопировать код, но ограничивается перечислениями с небольшим количеством значений.

Несколько более мощный подход, но тот, который должен использоваться с осторожностью, заключается в использовании некоторых бит значения для обозначения атрибутов чего-либо, в то время как другие биты идентифицируют элемент. Например, бит 30 может указывать на то, что персонаж является самцом, бит 29 может указывать на друга Гарри и т.д., В то время как младшие бит различают символы. Такой подход позволил бы добавить персонажей, которые могут быть или не быть друг-Гарри, не требуя кода, который проверяет, чтобы друг-Гарри изменился. Одно из предостережений заключается в том, что нужно различать константы перечисления, которые используются для установки значения перечисления, и те, которые используются для ТЕСТИРОВАНИЯ. Например, чтобы установить переменную, указывающую на Гарри, можно было бы установить ее в 0x60000001, но чтобы увидеть, есть ли переменная IS Harry, нужно протестировать ее с помощью 0x00000001.

Еще один подход, который может быть полезен, если общее число возможных значений является умеренным (например, 16-16 000 или около того), должно иметь массив флагов, связанных с каждым значением. Затем можно было бы скомпоновать что-то вроде "if (((characterAttributes [theCharacter] и chracterAttribute.Male)!= 0)". Этот подход будет работать лучше всего, когда количество символов довольно невелико. Если массив слишком велик, промахи в кеше могут замедляться вниз по коду до такой степени, что тестирование против небольшого количества символов индивидуально было бы быстрее.

Ответ 13

public static bool EqualsAny<T>(IEquatable<T> value, params T[] possibleMatches) {
    foreach (T t in possibleMatches) {
        if (value.Equals(t))
            return true;
    }
    return false;
}
public static bool EqualsAny<T>(IEquatable<T> value, IEnumerable<T> possibleMatches) {
    foreach (T t in possibleMatches) {
        if (value.Equals(t))
            return true;
    }
    return false;
}

Ответ 14

У меня была такая же проблема, но она была решена с помощью оператора switch переключатель (значение, которое вы включаете) { Дело 1:     код, который вы хотите выполнить; случай 2:  код, который вы хотите выполнить; по умолчанию:  вернуть значение }