Here is an example of my code. I need the last if to do nothing, else do something.
if (daPilot.Gas > 0)
;
else
daPilot.failMessage3();
You've already done it. Congratulations.
Of course the far less confusing design is to just NOT the condition and then have an if with no else.
if (daPilot.Gas > 0)
{
// nothing
}
else
{
daPilot.failMessage3();
}
Or more simply,
if (daPilot.Gas <= 0)
{
daPilot.failMessage3();
}
Two ways:
Empty curlys:
if (condition)
{
}
else
{
method();
}
Realize that you can simply invert the conditional:
if (!condition)
method();
There is no point of putting a condition for doing nothing. You should do it like this.
if (daPilot.Gas <= 0)
daPilot.failMessage3();
Simply invert the if condition and declare only the true part:
if (daPilot.Gas <= 0)
daPilot.failMessage3();
Anyway, you are always able to declare an empty body when needed: { }.
For instance:
while (condition)
{
}
Reverse the if:
if (daPilot.Gas <= 0) daPilot.failMessage3();
You can invert if, try this:
if (daPilot.Gas <= 0)
{
daPilot.failMessage3();
}
if you really want it to do nothing
{
if (daPilot.Gas > 0)
{
}
else
{
daPilot.failMessage3();
}
}
Let's use the '!' operator like:
if (!(daPilot.Gas > 0))
daPilot.failMessage3();
or with an extra variable:
var isGasGreaterToZero = daPilot.Gas > 0; /*true or false*/
if(!isGasGreaterToZero)
daPilot.failMessage3();
In both cases if daPilot.Gas is greater than zero (0) nothing will happen!
I like the following code - it uses zero or one line but need extend to tree lines
#pragma warning disable CS0642 // Possible mistaken empty statement
;
#pragma warning restore CS0642 // Possible mistaken empty statement
Also use { } in two lines or zero line in if statement:
if (...) { }
Inside the if statement write some code that does nothing:
if (daPilot.Gas > 0) var S = true;
I concur with the other answers here. Better to reverse the condition and if you dont want to do that, better to use the empty block { /* nothing */ }.
But now, suppose you are looking for a solution that:
Does not reverse the condition.
Does not use code blocks.
Does not generate a warning or an error or suppress such message.
Has minimal impact on generated compiler code.
How can you do that?
Answer: use _ = 0.
I came up with the following code example which is valid in .NET 3 and 5:
if (new Random().Next(2) == 0)
_ = 0; // do nothing
else
Console.WriteLine("Do Something");
If you ckeck at the compiler generated IL code without optimization you see the the instruction has been replaced by a nop.
With optimizations, the condition has been reversed by the compiler and the then part of the conditional is completely optimized away.
Conclusion: _ = 0; fits the bill.
Related
here is a function prints repeating int in a array.
in c#:
int [] ReturnDups(int[] a)
{
int repeats = 0;
Dictionary<int, bool> hash = new Dictionary<int>();
for(int i = 0; i < a.Length i++)
{
bool repeatSeen;
if (hash.TryGetValue(a[i], out repeatSeen))
{
if (!repeatSeen)
{
hash[a[i]] = true;
repeats ++;
}
}
else
{
hash[a[i]] = false;
}
}
int[] result = new int[repeats];
int current = 0;
if (repeats > 0)
{
foreach(KeyValuePair<int,bool> p in hash)
{
if(p.Value)
{
result[current++] = p.Key;
}
}
}
return result;
}
now converted to JAVA by Tangible software's tool.
in java:
private int[] ReturnDups(int[] a)
{
int repeats = 0;
java.util.HashMap<Integer, Boolean> hash = new java.util.HashMap<Integer>();
for (int i = 0; i < a.length i++)
{
boolean repeatSeen = false;
if (hash.containsKey(a[i]) ? (repeatSeen = hash.get(a[i])) == repeatSeen : false)
{
if (!repeatSeen)
{
hash.put(a[i], true);
repeats++;
}
}
else
{
hash.put(a[i], false);
}
}
int[] result = new int[repeats];
int current = 0;
if (repeats > 0)
{
for (java.util.Map.Entry<Integer,Boolean> p : hash.entrySet())
{
if (p.getValue())
{
result[current++] = p.getKey();
}
}
}
return result;
}
but findbug find this line of code as bugs. and it looks very odd to me too.
if (hash.containsKey(a[i]) ? (repeatSeen = hash.get(a[i])) == repeatSeen : false)
can someone pls explain to me what this line does and how do i write it in java properly?
thanks
You have overcomplicated the code for TryGetValue - this simple translation should work:
if ( hash.containsKey(a[i]) ) {
if (!hash.get(a[i])) {
hash.put(a[i], true);
}
} else {
hash.put(a[i], false);
}
C# has a way to get the value and a flag that tells you if the value has been found in a single call; Java does not have a similar API, because it lacks an ability to pass variables by reference.
Do not directly convert C# implementation. assign repeatSeen value only if the id is there.
if (hash.containsKey(a[i]))
{
repeatSeen = hash.get(a[i]).equals(repeatSeen)
if (!repeatSeen)
{
hash.put(a[i], true);
repeats++;
}
}
To answer the actual question that was asked:
if (hash.containsKey(a[i]) ? (repeatSeen = hash.get(a[i])) == repeatSeen : false)
is indeed syntactically wrong. I haven't looked at the rest of the code, but having written parsers/code-generators in my time I'm guessing it was supposed to be
if (hash.containsKey(a[i]) ? (repeatSeen = hash.get(a[i])) == repeatSeen) : false)
It's gratuitously ugly -- which often happens with code generators, especially ones without an optimizing pass -- but it's syntactically correct. Let's see if it actually does have a well-defined meaning.
CAVEAT: I haven't crosschecked this by running it -- if someone spots an error, please tell me!
First off, x?y:z is indeed a ternary operator, which Java inherited from C via C++. It's an if-then-else expression -- if x is true it has the value y, whereas if x is false it has the value z. So this one-liner means the same thing as:
boolean implied;
if (hash.containsKey(a[i]) then
implied = (repeatSeen = hash.get(a[i])) == repeatSeen);
else
implied = false;
if(implied)
... and so on.
Now, the remaining bit of ugliness is the second half of that and-expression. I don't know if you're familiar with the use of = (assignment) as an expression operator; its value as an operator is the same value being assigned to the variable. That's mostly intended to let you do things like a=b=0;, but it can also be used to set variables "in passing" in the middle of an expression. Hardcore C hackers do some very clever, and ugly, things with it (he says, being one)... and here's it's being used to get the value from the hashtable, assign it to repeatSeen, and then -- via the == -- test that same value against repeatSeen.
Now the question is, what order are the two arguments of == evaluated in? If the left side is evaluated first, the == must always be true because the assignment will occur before the right-hand side retrieves the value. If the right side is evaluated first, we'd be comparing the new value against the previous value, in an very non-obvious way.
Well, in fact, there's another StackOverflow entry which addresses that question:
What are the rules for evaluation order in Java?
According to that, the rule for Java is that the left argument of an operator is always evaluated before the right argument. So the first case applies, the == always returns true.
Rewriting our translation one more time to reflect that, it turns into
boolean implied;
if (hash.containsKey(a[i]) then
{
repeatSeen = hash.get(a[i]));
implied = true;
}
else
implied = false;
if(implied)
Which could be further rewritten as
if (hash.containsKey(a[i]) then
{
repeatSeen = hash.get(a[i]));
// and go on to do whatever else was in the body of the original if statement
"If that's what they meant, why didn't they just write it that way?" ... As I say, I've written code generators, and in many cases the easiest thing to do is just make sure all the fragments you're writing are individually correct for what they're trying to do and not worry about whether they at all resemble what a human would have written do do the same thing. In particular, it's tempting to generate code according to templates which allow for cases you may not actually use, rather than trying to recognize the simpler situation and generate code differently.
I'm guessing that the compiler was drawing in and translating bits of computation as it realized it needed them, and that this created the odd nesting as it started the if, then realized it needed a conditional assignment to repeatSeen, and for whatever reason tried to make that happen in the if's test rather than in its body. Believe me, I've seen worse kluging from code generators.
Resharper is telling me that the 'else' in this code is redundant:
if(a)
{
//Do Something
}
else if(b)
{
//Do Something
}
The else does not seem redundant because the else keeps b from being evaluated if a is true. The extra overhead is small if b is a variable, but b could also be an expression.
Is this correct?
It's redundant if you have a some sort of break, continue, return, or throw statement (or even a goto) inside the first if-block that always causes execution to branch outside the current block:
if(a)
{
return 0;
}
else if(b)
{
return 1;
}
In this case, if the code enters the first block, there's no way it will enter the second block, so it's equivalent to:
if(a)
{
return 0;
}
if(b)
{
return 1;
}
You are right in this case, but this is the reason I think they had it to begin with:
Certain if-else conditions can have their else clause removed. Consider the following method:
public int Sign(double d)
{
if (d > 0.0)
return 1;
else
return -1;
}
In the above, the else statement can be safely removed because its if clause returns from the method. Thus, even without the else, there’s no way you’ll be able to proceed past the if clause body.
It doesn't appear redundant to me. Removing the else would result in different program flow if both a and b are true.
I've come across a situation like this a few times:
while (true) {
while (age == 5); //What does this semi-colon indicate?
//Code
//Code
//Code
}
The while(true) indicates that this is an infinite loop, but I have trouble understanding what the semi-colon after the while condition accomplishes, isn't it equivalent to this?:
while (age == 5) { }
//Code
//Code
In other words, does it mean that the while loop is useless as it never enters the block?
while (age == 5); // empty statement
is equivalent to
while (age == 5) { } // empty block
Update: Even if there is no body to execute, doesn't mean that the loop terminates. Instead it will simply loop repeatedly over the conditional (which may have or rely upon side-effects) until it is satisfied. Here is the equivalent form with a goto:
loop:
if (age == 5)
goto loop;
This construct is sometimes used as a busy-loop waiting on a flag to be changed in threaded code. (The exact use and validity varies a good bit by language, algorithm, and execution environment.)
I find the use of ; for an "empty block" empty statement a questionable construct to use because of issues like this:
while (age == 5); {
Console.WriteLine("I hate debugging");
}
(I have seen this bug several times before, when new code was added.)
Happy coding.
while (age == 5); gets stuck into an infinite loop. In c ; is a null terminator. The compiler assumes that the above loop has only one statement that is ; which causes the loop to be iterated over infinitely.
a statement consisting of only
;
is a null statement. It is the same as a block (also called compound statement) with nothing inside
{
}
They both perform no operations.
If we put ; anywhere it means null statement (statement that does nothing).
When we write
while(true);
It means a while loop an a statement that does nothing. It is similar to the
while(true)
i++;
Here statement is not null but in the previous case statement was null.
Is there a way in .NET to replace a code where intervals are compared like
if (compare < 10)
{
// Do one thing
}
else if (10 <= compare && compare < 20)
{
// Do another thing
}
else if (20 <= compare && compare < 30)
{
// Do yet another thing
}
else
{
// Do nothing
}
by something more elegant like a switch statement (I think in Javascript "case (<10)" works, but in c#)? Does anyone else find this code is ugly as well?
One simplification: since these are all else-if instead of just if, you don't need to check the negation of the previous conditions. I.e., this is equivalent to your code:
if (compare < 10)
{
// Do one thing
}
else if (compare < 20)
{
// Do another thing
}
else if (compare < 30)
{
// Do yet another thing
}
else
{
// Do nothing
}
Since you've already affirmed that compare >= 10 after the first if, you really don't need the lower bound test on the second (or any of the other) ifs...
It's not pretty, but switch was originally implemented by hashing in C, so that it was actually faster than an if...else if chain. Such an implementation doesn't translate well to general ranges, and that's also why only constant cases were allowed.
However, for the example you give you could actually do something like:
switch(compare/10) {
case 0:
// Do one thing
break;
case 1:
// Do another thing
break;
case 2:
// Do yet another thing
break;
default;
// Do nothing
break;
}
Perhaps there is and I don't know about it and if so I would gladly like to be enlightened. I would like to be able to using something similar to the ?: operator but without having to include the : and without having to assign the result to a variable, like so:
q?r();
which would be semantically identically to
if (q)
{
r();
}
Edit: I should've expressed myself clearer. I'm looking for a way to get rid of the if's and else's and express the conditional statement with a more functional style.
Cheers,
/Christian
if (q) r();
That's about as terse as you can get with it.
Sometimes you can save writing if statements by using LINQ.
For example, instead of:
int CountItemsLargerThanFive(IEnumerable<int> collection)
{
int count = 0;
foreach (var item in collection)
{
if (item > 5)
{
count++;
}
}
return count;
}
You can write:
int CountItemsLargerThanFive(IEnumerable<int> collection)
{
return collection.Count(item => item > 5);
}
No if's!
And there are many other cases in which control structures such as if can be replaced by LINQ.
If you want to execute a single statement, you can omit the brackets and write it on a single line:
if (q) r();
Normally it's more readable to have the condition and the code on separate lines, and always include the brackets, but if both the condition and the code are simple, the readability should not be a problem.
Example:
if (line > 0) builder.AppendLine();
as an alternative to:
if (line > 0) {
builder.AppendLine();
}
As others have mentioned, stick with the obvious route.
For fun, here's a way to use the conditional operator like you'd wanted, with delegates (please don't do this):
(q ? (Action)r : () => { })();
which looks slightly nicer if there were a genuine else:
(q ? (Action)trueAction : falseAction)();
you can also use : x ?? 0
this is the null checking