Boolean expressions, why only two terms?

Given that it is valid for recording

a = b = c = 2; 

It would be nice, not

 bool allTwo = a == 2 && b == 2 && c == 2; 

write instead

 bool allTwo = a == b == c == 2; 

But I can not, because a == b evaluates a boolean value, which then can not be compared with an integer.

Is there a reason for the language wording that was implemented this way?

+4
source share
8 answers

The type of the expression a == b is logical, so you either have to break the rule that the expression means the same thing, regardless of its context, or have n-ary == operators, so a == b == c parsed as (== abc) , not (== (== ab) c) . This means that you need to have (a == b) == c to compare boolean c with the result (a == b) , which is fine, but not with the simple grammar style C, which C # is in the tradition of.

+8
source

Well, the expression c == 2 will return true , so b will be compared with true , not 2.

Edit: Most likely, this is implemented in the way that C-style languages โ€‹โ€‹handle Boolean expressions. They would have to make a special exception for several terms and implement it differently, while with the assignment operator it is simpler: the correct expression expresses a value that can be logically applied to the next expression in the chain. Designers seem to have taken a simple approach.

+5
source

From my point of view, this is a matter of clarity. If the decision depended on me, I would have thought that adding such a language feature might add too much ambiguity about how complex expressions are evaluated. Is == b == c different from (a == b) == c in certain situations? What if I really want to compare c with the boolean result a == b, rather than compare c with b? In most cases, the compiler can probably determine the correct comparison, but if c is implicitly converted to bool, although unlikely, then this is impossible to say.

So I'm not sure what it is worth it. Although this may not look so syntactically strong, you can create your own utility function to compare the equality of several objects, for example below:

  public static bool Equals(this object x, params object[] y) { for (int i = 0; i < y.Length; i++) { if (!object.Equals(x, y[i])) return false; } return true; } 

Then you can use it as follows:

  if (a.Equals(b, c, d, e, f, g)) { // ... } 
+3
source

I canโ€™t find a quote, but I think that it was best used by Eric Lippert (?): Not implement the function for free. See also http://blog.ryjones.org/2005/07/12/product-development/ and http://blog.ryjones.org/2005/07/12/product-development/

They have many opportunities for implementation, and I canโ€™t imagine that something non-standard, like this, with dubious value, will have high priority. I am not saying that this is not valuable, but it can lead to confusion, probably will not be used very often, etc. I think a1ex07 also makes sense. This should be common, as it can no longer be processed at all (== always returns a boolean, etc.)

Now you can do the same with LINQ, but the syntax is a bit confusing and requires some sort of array allocation:

 bool allTwo = new int[] { a, b, c }.All(i => i == 2); 

You can do it back and check if! = 2:

 bool allNotTwo = new int[] { a, b, c }.Any(i => i != 2); 

In both cases, it will also stop working as soon as one turns out to be invalid, so you often won't see the whole list.

Edit: Here's another point: Does C # have too many language features?

something new will be very useful for turning it into a language

+2
source

To do what you want, operator == must return an object. In this case, we will have another problem - now we need to implicitly convert any object to boolean. Such a conversion will also create additional problems.

+1
source

I think you are a little doubtful about your starting point.

There is nothing magical about a = b = c = 2 to suggest that a == b == c == 2 should work the way you want - in fact, more - on the contrary.

An assignment operator is defined only for two operands and returns the given value. A line of them simply passes the value from each statement to the following:

 1: a = (b = (c = 2)); 2: a = (b = (2)); 3: a = (2); 

So the same is true for a == b == c == 2 :

 1: bool allTwo = (a == (b == (c == 2))); 2: bool allTwo = (a == (b == ([Boolean]))); 3: bool allTwo = (a == ([Boolean])); 4: bool allTwo = ([Boolean]); 

So the technical reason is that C# does not contain a definition for a special call for a statement string.

Regarding language design and implementation, the reason is probably to prevent ambiguity and additional complexity. Although you may need a == b == c == 2 , which is now defined as all equal , on the next line you might really need it to be running now. How should behavior be distinguished? And would it really be worth the effort to implement?

Or is a == 2 && b == 2 really that bad ?;)

+1
source

Ignoring return values, this is also associated with associative association .

Assignment operators are right-associative. That is, the right side of the assignment operator is evaluated first. This is why you can make a = b = c = 2 and assign them all 2. If you do, you will get a , the old value of b and b , with the old value of c .

Most of the other operators are left-associative, especially the logical short-circuit operators ( && and || ). That is, a == b or a && b first evaluates a .

You can argue that == can be right-associative ... except in .NET it cannot, because for objects a == b (if not overridden) is converted to a.Equals(b) (or this is a.ReferenceEquals(b) ... I never remember).

+1
source

Not a direct answer to your question, but what about:

 bool allTwo = a & b & c == 2; 

EDIT: As Pete says, this will not work. Like this?

 bool allEqual(params int[] inputs) { int lastval = inputs[0]; for (int i = 1; i < inputs.length; i++) { if (lastval != inputs[i]) return false; lastval = inputs[i]; } return true; } 

Declare it once, use it whenever you want, using a list of integers separated by commas. (There is probably an even simpler function for it, but whatever.)

 bool allTwo = a == b && b == c && c == 2; // prefer this format over a == 2 && b == 2 && c == 2, personally 

against

 bool allTwo = allEqual(a, b, c, 2); 

There is not much to say for me regarding the question itself, which has not yet been discussed in the answers of others.

-1
source

Source: https://habr.com/ru/post/1312341/


All Articles