Действительно ли возможно осуществить рефакторинг этот C# если (..) оператор?

простой вопрос:-

у меня есть следующее простое если (..) операторы:-

if (foo == Animal.Cat || foo == Animal.Dog)
{ .. }

if (baa == 1|| baa == 69)
{ .. }

действительно ли возможно осуществить рефакторинг их во что-то как...

Отказ от ответственности: Я знаю, что это не компилирует.. но это - вид того, что я пытаюсь получить...

if (foo == (Animal.Cat || Animal.Dog))
{ .. }

if (baa == (1 || 69))
{ .. }

Аплодисменты :)

Править

Интересно, могло ли расширение лямбда-выражения сделать это?:P

7
задан Pure.Krome 3 April 2010 в 11:30
поделиться

7 ответов

Обычно я создаю метод расширения под названием IsIn () , который принимает общий массив параметров типа , а затем вызывает .Contains () для это, передавая экземпляр, на котором вызывается расширение.

Похоже, if (foo.IsIn (foo1, foo2)) . Очень просто писать, очень легко использовать.

13
ответ дан 6 December 2019 в 09:18
поделиться

В этом конкретном случае, когда у вас есть только два варианта, от этого мало толку, но если их может быть много, вы можете поместить их в список а затем используйте Contains следующим образом:

List<Animal> allowedAnimals = new List<Animal>
{
    Animal.Cat,
    Animal.Dog,
    Animal.Fish,
    Animal.Frog,
    Animal.Horse
};

if (allowedAnimals.Contains(animal))
{
    // etc...
}

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

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

3
ответ дан 6 December 2019 в 09:18
поделиться

Для этого можно использовать метод Extension:

public static bool IsAny<T>(this Enum value, params T[] values)
        {
            foreach (T e in values)
            {
                if (value.Equals(e)) return true;
            }
            return false;
        }

usage:

enum TestEnum
    {
        Stackoverflow,
        overflowStack,
        stackstack
    }

TestEnum val = TestEnum.overflowStack;

Console.WriteLine(val.IsAny(TestEnum.stackstack, TestEnum.Stackoverflow));  //false
Console.WriteLine(val.IsAny(TestEnum.overflowStack, TestEnum.Stackoverflow)); // true
2
ответ дан 6 December 2019 в 09:18
поделиться

Я мало что знаю о .NET 4.0 (на данный момент использую 3.5), но думаю, что нет никакого способа добиться эффекта, который нужен Pure.Krome.

Но приближение к этому виду сравнения может быть достигнуто с помощью массивов и методов расширения, предоставляемых LINQ.

Вот небольшой пример.

string foo = @"very weird";
if (new[] { @"don't do it", @"very weird" }.Contains(foo))
{
    Console.WriteLine(@"bingo string");
}
int baa = 7;
if (new []{5, 7}.Contains(baa))
{
    Console.WriteLine(@"bingo int");
}

Это выводит:

bingo string
bingo int

Этот способ потребляет больше ресурсов, чем простая цепочка сравнений и логических операторов, но обеспечивает синтаксис, аналогичный тому, который хочет получить Pure.Krome.

Если вы не хотите определять массивы с помощью new [] (это действительно некрасиво в логических условиях), вы можете сами определить для этого метод расширения.

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

Итак, вы можете использовать этот метод расширения:

if (baa.IsOneOf(5, 7, 9, 10))
{
    Console.WriteLine(@"bingo int");
}

Вывод действительно предсказуем, хех.

1
ответ дан 6 December 2019 в 09:18
поделиться

Еще один способ сделать это - разделить правила и логику, которая должна выполняться, когда любое / все из них истинны:

var animal_rules = new Func<Animal, bool>[]{
 (a) => a == Animal.Cat,
 (a) => a == Animal.Dog
};

var baa_rules = new Func<int, bool>[]{
 (b) => b == 1,
 (b) => b == 69
}

Затем вы можете использовать правило с помощью .Any () и / или All () для выполнения соответствующих операций, например:

if(animal_rules.Any(rule => rule(foo)){
 // animal logic here...
}

if(baa_rules.Any(rule => rule(baa)){
 // baa logic here...
}

HTH

0
ответ дан 6 December 2019 в 09:18
поделиться

Думаю, лучший вопрос - зачем вообще об этом беспокоиться? Это ясно как есть. Бьюсь об заклад, если бы вы разместили больше своего кода, в первую очередь нужно было бы решить многие другие вопросы.

0
ответ дан 6 December 2019 в 09:18
поделиться

Вы можете использовать переключатель с провалом (уродливое наследие синтаксиса C):

switch (foo) {
    case Animal.Cat:
    case Animal.Dog:
    {
        ...
        break;
    }
}

Однако будет работать только для таких тривиальных примеров, и я бы посоветовал придерживаться if в любом случае.

1
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: