views:

209

answers:

8

Hi folks,

simple question :-

i have the following simple if (..) statements :-

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

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

is it possible to refactor these into something like ...

DISCLAIMER: I know this doesn't compile .. but this is sorta what i'm trying to get...

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

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

Cheers :)

EDIT

I wonder if a lambda expression extension could do this? :P

+1  A: 

You can use switch with fallthrough (an ugly heritage of C syntax):

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

Will only work for such trivial examples, though, and I'd suggest sticking to if in that case anyway.

Joey
+12  A: 

I usually create an extension method called IsIn() that takes a generic parameter array of type <T> and then calls .Contains() on it, passing the instance on which the extension is called.

It looks like if (foo.IsIn(foo1, foo2)). Very simple to write, super easy to use.

Seth Petry-Johnson
I like that :) not sure if i'll use it though, but that's a kewl answer. cheers!
Pure.Krome
+3  A: 

It's not much use in this specific case where you only have two options, but if there could be many options you might prefer to put the options in a list and then use Contains like this:

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

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

This method will also work on other types than enums including types that you cannot switch on. It is also useful if the list of allowed values will only be known at runtime.

Note that if you create a new list each time there will be a performance penalty.

Mark Byers
+2  A: 

You could use an Extension method for that:

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
Stormenet
+1  A: 
cat.Foo();

Where Cat and Dog derive from animal and do not override the Foo method. if else can be substituted by polymorphism in many cases.

Hasan Khan
A: 

I don't really know much about .NET 4.0 (using 3.5 for now) but I think there are no way to achieve effect Pure.Krome want.

But approximation to this kind of comparing can be achieved by using arrays and extension methods LINQ provides.

Here is the little example.

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");
}

This outputs:

bingo string
bingo int

This way is more resource devouring than simple chain of comparsions and logical operators but provides syntax similar to one Pure.Krome wants to get.

If you are don't want to define arrays with new[] (it's really kinda ungly in logical conditions) you can define yourself extension method for this.

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

So you can use this extension method:

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

Output is really predictable, heh.

Eskat0n
A: 

One more way of doing this is by separating out the rules & the logic which needs to be performed when any/all of them are true by:

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
}

Then, you can consume the rule by the .Any() and/or All() to do the relevant operations like:

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

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

HTH

Sunny
A: 

I think a better question is why bother worrying about this at all? It is clear as it stands. I bet if you posted more of your code there would be many other things that should be addressed first.

Larry Watanabe
Wow dude - ouch.
Pure.Krome