简体   繁体   中英

C# Comparison shorthand

I have this code:

    if (y == a && y == b && y == c && y == d ...)
    {
        ...
    }

Is there some form of shorthand so that I can rewrite it as something like this?

    if(y == (a && b && c && d ...))
    {
        ...
    }

The functionality should be exactly the same. I'm just looking for something that looks less confusing.

EDIT Sorry for not clarifying, all the variables are integers. I'm looking for a shorter way to ensure that a , b , c , d , ... all equal y .

The closest you're going to get (without implementing your own kind of mechanism):

if (new[] { a, b, c, d }.All(value => y == value))
    // ...

No , there isn't anything that will simplify your code without outweighing the readability benefits with a big performance penalty.


Edit: High-performance solution

If you're desperate enough to try a high-performance solution, here's one:

(Update: Apparently I was wrong in thinking you can use generics with varargs; you apparently can only hard-code the types. So I changed the type below to int instead, but the same code applies.)

static bool AllEqual(int value, __arglist)
{
    for (var ai = new ArgIterator(__arglist); ai.GetRemainingCount() > 0; )
    {
        var next = __refvalue(ai.GetNextArg(typeof(int).TypeHandle), int);
        if (!value.Equals(next)) { return false; }
    }
    return true;
}

Then try calling it with:

//...
bool equal = AllEqual(1, __arglist(1, 1, 1));

Warning: People will probably yell at you for doing this, so use it at your own risk. :)

Slightly more readable (in my opinion) is:

if ((y == a) && (y == b) && (y == c) && (y == d) ...)

but I don't believe there's anything in the base language for this.

If you really want something like what you propose, that's what functions are for, something like:

if (isSetToAll (y, a, b, c, d, ...))

but you might want to be careful on the performance front.


One thing may be of use to you if that's being done in a loop where a/b/c/d/... are invariant (in other words, where only y is changing).

Check the equality for the invariants outside the loop:

if ((a == b) && (a == c) && (a == d) ...)

because, if that's not the case, then y can never be equal to all of them. Then, inside the loop, just do:

if (y == a)

The fact that you already know that all the non- y variables are equal to each other means that you only need to check y against one of them.

But, since I haven't seen your complete code, I'm not sure if it will be useful to you.


I should mention that, while verbose, there's nothing actually unreadable about your original code, especially if it's formatted nicely. Even the behemoth:

if ((y == a) && (y == b) && (y == c) && (y == d) &&
    (y == e) && (y == f) && (y == g) && (y == h) &&
    (y == i) && (y == j) && (y == k) && (y == l) &&
    (y == m) && (y == n) && (y == o) && (y == p) &&
    (y == q) && (y == r) && (y == s) && (y == t) &&
    (y == u) && (y == v) && (y == w) && (y == x))
{
    ...
}

is readable (though I'm not a big fan of terse variable names).

Of course, at that point, you may want to look into using arrays with loops rather than singular variables.

No, there isn't. Stick with what you have.

Well, you could write a public static bool AllEqual<T>(params T[] values) (maybe with overloads for 2/3/4/5 operands to avoid the array creation), but I'm not sure it is worth it most times.

Try this:

Assuming you're comparing strings

IList<string> valuesToCompare = new List<string> { "a", "b", "c", "d" };

if (valuesToCompare.Any(valueToCompare => valueToCompare != y)) 
       //If there is any value that is not equal to y
       //Do something
new[] { a, b, c, d }.Contains(y)

Although it's impossible to be sure, I'd look at your overall code structure and see if there isn't just a better way to handle that whole area.

Any time you have a pattern that repeats like that, you will probably have to modify it a lot. Chances are that you will need to add a new q==y or change something eventually.

A lot of people here were concerned with performance, but it's much more important to make sure your code is maintainable and understandable and properly factored.

As a total guess, I'd say that your a,b,c,d variables should all be a member of 4 different objects, ax, bx, cx, dx what do a,b,c,d represent? They can't just be arbitrary numbers, they are prices or pixel locations or weights of elements--something! I can't imagine a condition where you'd have exactly 4 and never 5 or 3 of something.

Anyway, whatever it represents, there are probably other things associated with it--a name, size, color, control index--whatever.

In general I'd look at a higher level for a fix to this problem. I'd say at least a,b,c & d should be something defined outside the program, either in a data file or database.

For if (y == a && y == b && y == c && y == d) , use:

if ( y == a == b == c == d) { //code here }

For if (y == a || y == b || y == c || y == d) and y is a simple type or string, use:

switch(y)
{
   case a:
   case b:
   case c:
   case d:
     //your code here
     break;

}
   bool  x=true ,y=true, z=true, p = true;

    if (x == (y == z == p)) //true

    x = false;
    if (x == (y == z == p)) //false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM