2

I was wondering if it is possible to use a keyword like "IN" to test a condition in an if statement in C# ?

original code :

if (fAuth.ShowDialog(this.DialogParent) == DialogResult.Cancel 
|| fAuth.ShowDialog(this.DialogParent) == DialogResult.Abort 
|| fAuth.ShowDialog(this.DialogParent) == DialogResult.None
|| fAuth.ShowDialog(this.DialogParent) == DialogResult.No)
return;

I'm asking how to do something like this:

if (fAuth.ShowDialog(this.DialogParent) IN (DialogResult.Cancel,DialogResult.Abort,DialogResult.None,DialogResult.No)
return; 

What would be the correct syntax ?

user2711965
  • 1,795
  • 2
  • 14
  • 34
Martin Lebel
  • 497
  • 1
  • 6
  • 13
  • The original code will be systematically more efficient than any of the collections-based suggestions. – zneak Apr 17 '15 at 15:18
  • @CodeCaster, notwithstanding any bugs in the current code, the method of checking will be systematically more efficient than any collections-based suggestion. – zneak Apr 17 '15 at 15:20
  • @zneak "more efficient" is usually irrelevant. Sure, creating a collection (of whatever kind) may have some overhead as opposed to executing some `or`s , but it won't be noticeable at all unless executed millions of times in a tight loop. – CodeCaster Apr 17 '15 at 15:21
  • And how many times will you read the array to compensate? The truth is that both have very little impact. You are also the only person to have the array declaration on a different line, and that's after an edit. Most of the suggestions aren't even more readable. – zneak Apr 17 '15 at 15:22
  • Your first comment _"systematically more efficient"_ makes it sound like a big deal, which it isn't. Don't mention performance unless it has a big impact or is specifically requested. I do agree with the readability though, that's exactly why I edited. – CodeCaster Apr 17 '15 at 15:23
  • The subtext is that the method of checking that OP had doesn't need fixing. In this context, it makes sense to tell about the other advantages of the solution, doesn't it? – zneak Apr 17 '15 at 15:30
  • OP's code did need fixing, as it has too much repetition and higher maintenance cost (adding an option requires the editor to copy an entire `|| result == DialogResult.Whatever` line, as opposed to adding `DialogResult.Whatever` to the array). The former is more error-prone than the latter. – CodeCaster Apr 17 '15 at 15:32

5 Answers5

6

I think the pinpoint exact answer to your question is like CodeMaster already indicated at if statements matching multiple values

That being said, since you are checking for a DialogResult, in this specific case, I doubt performance considerations come into play and we look more into code readability (as you likely won't popup 10,000 dialogs to the user).

The simplest solution is a switch statement to increase readability:

switch(fAuth.ShowDialog(this.DialogParent))
{
    case DialogResult.Cancel:
    case DialogResult.Abort:
    case DialogResult.None:
    case DialogResult.No:
        return;
    default:
        break;
}

The problem with that is that you possibly have to duplicate code if you want to check the same thing in multiple places. In that case I would suggest to wrap this into a function like that (change the name to your liking):

public class DialogEvaluator
{
    public static bool IsResultNegative(DialogResult result)
    {
        switch(fAuth.ShowDialog(this.DialogParent))
        {
            case DialogResult.Cancel:
            case DialogResult.Abort:
            case DialogResult.None:
            case DialogResult.No:
                return true;
            default:
                return false;
        }
    }
}

//And use it like that:
if(DialogEvaluator.IsResultNegative(fAuth.ShowDialog(this.DialogParent))
{
    return;
}

If you have however a bunch of different cases with different requirements, then I would go back again to the Generic In Method and wrap the possible outcomes in well named Lists:

public static class DialogEvaluator
{
    public static bool In<T>(this T obj, IEnumerable<T> args)
    {
        return args.Contains(obj);
    }

    static DialogEvaluator
    {
        NegativeResult = new List<DialogResult>() { DialogResult.Cancel, DialogResult.Abort, DialogResult.None, DialogResult.No };
        SpecificNegativeResult = new List<DialogResult>() { DialogResult.Cancel, DialogResult.Abort, DialogResult.No };
    }

    public static List<DialogResult> NegativeResult {get; private set;}
    public static List<DialogResult> SpecificNegativeResult {get; private set;}
}

//And use it like that:
if (fAuth.ShowDialog(this.DialogParent)
     .In(DialogEvaluator.NegativeResult)
{
    return;
}
//Or
if (fAuth.ShowDialog(this.DialogParent)
     .In(DialogEvaluator.SpecificNegativeResult)
{
    return;
}

It depends on your circumstances and you have to balance readability, maintainability and conciseness.

Community
  • 1
  • 1
Frank J
  • 1,666
  • 13
  • 19
  • 1
    Frank is right. Since you have so few conditions, the readability this provides will generally trump other solutions. – Ken Palmer Apr 17 '15 at 16:28
2

the best analog i can think of is an extension method In

public static class Helper
{
    public static bool In<T>(this T value, params T[] args)
    {
        for (int i = 0; i < args.Length; i++)
            if (Object.Equals(value, args[i]))
                return true;
        return false;
    }
}

in your situation it can be invoked as

 if (fAuth.ShowDialog(this.DialogParent)
     .In(DialogResult.Cancel,DialogResult.Abort,DialogResult.None,DialogResult.No))

but be aware of slow execution, if number of invokations is really large

ASh
  • 34,632
  • 9
  • 60
  • 82
1

you can look into the LINQ contains method:

var acceptable = new List<DialogResult> {DialogResult.Cancel, DialogResult.Abort};
return acceptable.Contains(myResult);
LiamK
  • 795
  • 6
  • 16
1

Use a switch statement. Or, you can write an extension method, as suggested in this SO post. https://stackoverflow.com/a/3907357/993856

Community
  • 1
  • 1
Ken Palmer
  • 2,355
  • 5
  • 37
  • 57
0

or simply:

(new List<DialogResult> {DialogResult.Cancel, DialogResult.Abort, DialogResult.None, DialogResult.No }).Contains(myResult);
z0mbi3
  • 336
  • 4
  • 14