Why are there no ||= or &&= operators in C#?

14,022

Solution 1

Why did the logical operators get left out? Is there a good technical reason why it is hard?

They didn't. You can do &= or |= or ^= if you want.

bool b1 = false;
bool b2 = true;
b1 |= b2; // means b1 = b1 | b2

The || and && operators do not have a compound form because frankly, they're a bit silly. Under what circumstances would you want to say

b1 ||= b2;
b1 &&= b2;

such that the right hand side is not evaluated if the left hand side does not change? It seems like only a few people would actually use this feature, so why put it in?

For more information about the compound operators, see my serious article here:
https://docs.microsoft.com/en-us/archive/blogs/ericlippert/compound-assignment-part-one

and the follow-up April-Fools article here:
https://docs.microsoft.com/en-us/archive/blogs/ericlippert/compound-assignment-part-two

Solution 2

maybe just use

isAdmin = isAdmin || IsGroupAdmin()

I guess it is partially because a ||= b is kind of confusing because there might be two versions of the implementation: a = a || b, or a = b || a. And they act differently because the right-hand side of the expression is sometimes not evaluated.

Share:
14,022

Related videos on Youtube

George Duckett
Author by

George Duckett

This is just here so I get the nice drop-shadow!

Updated on November 11, 2020

Comments

  • George Duckett
    George Duckett over 3 years

    We have equivalent assignment operators for all Logical operators, Shift operators, Additive operators and all Multiplicative operators.

    Why did the logical operators get left out? Is there a good technical reason why it is hard?

    • Matt Ellen
      Matt Ellen almost 13 years
      Is there a reason why you'd use them?
    • Fosco
      Fosco almost 13 years
      Can you provide an example where they would be useful?
    • Orace
      Orace over 2 years
  • Ben Voigt
    Ben Voigt almost 13 years
    I've wanted short-circuiting compound assignment before. No one uses them because they don't exist. See also stackoverflow.com/questions/2324549 which gives a number of example use cases.
  • Ed S.
    Ed S. almost 13 years
    Can you please explain the "only a few people will use it, it adds complexity, and there is an existing way to accomplish the stated goal anyway" argument to some (not to be named) members of my company? I've tried and apparently failed. :)
  • daver
    daver almost 11 years
    re: "Under what circumstances would you want to say b1 ||= b2; ..."? These circumstances: I have an array of elements and need to test some condition for each element, so I loop through the array and create a 'running total' of sorts: result=TRUE; for (i...) {result &&= a[i];} Or I might want to do a running total of 'OR's. In fact, I had just such a situation in a project I'm working on now. Is that so silly?
  • Brad Larson
    Brad Larson about 8 years
    To Slipp D. Thompson: your comments, as well as others in this conversation, were deleted by moderators in response to multiple flags from the community. This conversation was not going in a very constructive or positive direction. Eric has no ability to delete comments himself.
  • Eric Lippert
    Eric Lippert about 8 years
    @daver: Sorry I missed your comment when it was posted. Though that seems plausible, there are more efficient idioms that you could use for those scenarios. array.All(x=>x) is maybe a little hard to read, but it has the same semantics as the iterated && operation you propose and it bails out when the first false is detected rather than continuing to iterate over the array trying to make the expression true. Similarly for array.Any(x=>x) for iterated ||.
  • Eric Lippert
    Eric Lippert about 8 years
    @daver: Moreover: the point of &&= over &=, which you already have, would be to avoid the cost of the right hand side when the left hand side is false. Does that really avoid a cost in your case? You are trading a test and a branch in exchange for skipping an array read -- cheap -- and a logical and -- super cheap! This would be in many cases larger, slower code. Larger code means more frequent cache misses, more branches means more opportunities for the branch predictor to get it wrong. More basic blocks means the jitter has more work to do. Not worth it.
  • Chris Petheram
    Chris Petheram over 6 years
    I suspect I fall squarely in the "only a few people" category, but I want to perform a sequence of expensive (in time and money) hardware operations, only if the previous operation succeeded. In this case &&= would be very useful. Though I guess short circuiting with an exception is just as good.
  • Ole Albers
    Ole Albers over 6 years
    I strongly disagree about the sillyness :) I just had the following requirement: isAdmin |= IsGroupAdmin(); isAdmin |= IsCompanyAdmin(), where IsGroupAdmin() and IsCompanyAdmin() are expensive methods that require database-Selects. In these cases I cannot use |= obviously for performance reasons and have to use isAdmin=isAdmin ||... and a ||= would really help.
  • Tanktalus
    Tanktalus about 6 years
    &&= and ||= are far from silly. When the RHS is expensive, they are very useful. Whether that's a db lookup or a URL fetch or a regex match or ... there are tons of serious use cases for such an operator. (??= also falls into the same category - if it's null, then do this big expensive operation to determine a value). I have a hard time taking someone seriously who thinks this is silly.
  • Yarl
    Yarl over 3 years
    For me these 2 are validly complemental. Exactly in the way it was said by @EricLippert (_ … such that the right hand side is not evaluated if the left hand side does not change?_). E.g userHasFeatureEnabled &&= !DidAdminRemovedUsersFeatureRight().
  • Hagen von Eitzen
    Hagen von Eitzen about 3 years
    Non sequitur. There is a -= b and no-one is confused that there might be an implementation a = b - a instead of a = a - b