tags:

views:

221

answers:

5
int a, b, c, d, e;
a = b = c = d = e = 1;

if ((a==b) && (b==c) && (c==d) && (d==e))
{
    Console.WriteLine("that syntax is horrible");
}

is there a more elegant way to test multiple equality as above?

maybe an AreEqual(params obj[]) or something? I had a google but didn't find anything.

+3  A: 

No, that's the most reasonable way (i mean the most readable, which is the most important).

The real question is, why do you need to do that? It seems like a bad design in the first place ...

Noon Silk
how on earth can it be bad design to need to test if a bunch of things are equal? are you honestly saying that there is no possible reason to ever need to do this? this is exactly the kind of 'generic opinion' comment that I find so frustrating with this site. Would you like me to post all 50K lines of code, so you can understand why I want to do this?
fearofawhackplanet
Pretty much I am saying that yes; no particular reason to get upset at my response though. I will leave you to it.
Noon Silk
I don't think he meant to imply that you would never need to test if a bunch of things are equal, just that there may be a more concise way of doing things (depending on the rest of your code).
Justin R.
+10  A: 

A possible implementation of AreEqual(params object[] objects):

(Following Jon Skeet's advice, here's a generic version)

bool AreEqual<T>(params T[] objects)
{
    if (objects.Length <= 1) return true;
    return objects.Skip(1).All(x => x.Equals(objects[0]));
}

The Skip(1) is not strictly necessary either.

Aviad P.
yeah, linq is the way to go :-)
David Schmitt
thanks Aviad, I know it's trivial to implement, just thought there might already exist a suitable method.
fearofawhackplanet
I would make it a generic method instead of taking `object[]` though...
Jon Skeet
@fearofawhackplanet I didn't mean to offend, but I am not familiar with a BCL function that does the same.
Aviad P.
@Aviad, looks like there isn't one, so you get the answer points anyway :)
fearofawhackplanet
You're still going to box when you call Equals here, because it'll call Equals(object). My solution avoids that.
Jon Skeet
+4  A: 

Here's a generic version which will avoid boxing (and be more type-safe at compile time):

public static bool AllEqual<T>(T firstItem, params T[] items)
{
    // Omitted error checking
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    foreach (T item in items)
    {
        if (!comparer.Equals(firstItem, item))
        {
            return false;
        }
    }
    return true;
}

Note that this won't be as convenient if you really want to pass a bunch of values you've already got in an array, but avoids problems with empty arrays - and means you don't have any redundant comparisons.

Jon Skeet
This isn't the same as the orignal; (if you override 'Equals' this will use that implementation).
Noon Silk
@silky: Which version are you suggesting wouldn't use the overridden Equals? The only difference would be if someone implemented Equals(object) in a different way to their implementation of IEqualityComparer - in which case they've got bigger problems IMO.
Jon Skeet
Jon: The *original* (i.e. the OPs code). And no, it would make a difference if he actually wanted to do a reference compare. It's pretty unlikely, for sure, but it shows the harmfulness of a naive conversion to some elaborate scheme that is ultimately, IMHO, less readable and not even required.
Noon Silk
@silky: you **cannot** implement a generic method that uses `==` for comparison in .NET. `Equals` is the only way, and guaranteed by the implementation guidelines to be consistent with `==`’s implementation. If reference equality is the required operation, simply create an extra overload. But your assumption that the OP probably meant reference equality (despite his example being with `int`s) is completely weird.
Konrad Rudolph
Konrad: Re your first point: that's exactly what I'm saying. I'm sitting here fairly flabbergasted that I am even having a conversation about something so completely ridiculous as a generic method for comparing the exact equality of a list of objects. It's just very strange, when there are so many better ways to do this. I won't waste anymore time here.
Noon Silk
@silky: no, please indulge me. SO may not be good for discussion but it’s about solutions, and I fail to see how Jon’s isn’t a good solution. What is so “completely ridiculous” and “strange” about this method? – Always provided the users know what they do and that they follow the guidelines for implementing `Equals` – but this is *always* required when working with the .NET libraries so it should go without saying.
Konrad Rudolph
Konrad: You show *me* an example of when you would ever use this. A real example. I say to you, you won't come up with one that wouldn't be better done via the use of a set/pattern/switch/general redesign. Jon's provided a "solution" to a problem that shouldn't be solved. The OP is clearly a newbie, and this approach (and the accepted one) are, IMHO, bad practice. But, sadly, I've noticed this previously with Jon (and others) and it doesn't seem to matter to them, which I find really confusing. Surely it's not about being the 'coolest' with LINQ, etc, it's about what is best.
Noon Silk
@silky: Isn’t that an entirely different discussion? For what it’s worth, I don’t know any use case off the top of my head. On the other hand, a lot of people seem to find it useful enough that Python has introduced a special syntax for it (`a == b == c == d`). Is this a priori bad design? That sounds a bit over-generalizing.
Konrad Rudolph
@silky: The original, the OP's code, is only using ints. How would you override int's implementation of `Equals`? As for whether this is ever useful - I can imagine there are cases where you *do* want to for equality for a whole sequence, but you've *assumed* it's bad design.
Jon Skeet
@silky: As for your comment about providing answers to things which shouldn't be done - see http://stackoverflow.com/questions/2020373 for a counterexample. Has it occurred to you that maybe we just disagree about which things definitely shouldn't be done, and which might actually have a good reason behind them?
Jon Skeet
Jon: I'm not saying you do it all the time, and I'm not saying it's limited to you, but it happens more often than it should (with lots of posters). Konrad: No, it's not an entirely different question; it's *exactly* the point here: the poster has a problem he's trying to solve the "best" way, but the underlying approach is wrong. So it's appropriate to make that clear (at least, that's what I prefer to do). I'm merely disagreeing with Jon's approach here, and highlighting the error. Jon: As with Konrad, feel free to explain exactly how it could *possibly* be good.
Noon Silk
A: 

If you're comparing simple types and you only have a few use cases then you could create a few utility methods such as:

    bool AllEqual(int first, params int[] numbers)
    {
        return numbers.All(x => x == first);
    }
Jamie Ide
A: 
mcintyre321
Konrad Rudolph
heh so it is :)
mcintyre321