C# IF statements, and doing things very specifically from which is true - c#

So, to start, I have seen posts like this: How to find which condition is true without using if statement
It's not quite what I need, although the idea is pertinent, in that I would like it to be more readable code.
I think Switch is the best bet, but let me explain.
I have this statement:
if (input == string.Empty || typeComboBox.Text == null)
{
MessageBox.Show("Nothing to encrypt!", "Nothing Selected!");
return null;
}
So the idea here is that I used to have this statement broken into two "IF" statements, which isn't a huge deal, but for readability sake, and my on going effort of reducing code, I wanted to combine the statements into one.
If input is empty, I want the first argument in MessageBox.Show to appear, but not the second.
If typeComboBox.Text is null, I want the second option to appear, but not the first.
If they are both true statements, I want both to appear.
Now, my goal was to have these both done without the use of more than one test or method. Basically, I mean this: if I can find which condition is true and have the resultant data output within the same statement, that would be ideal.
I see switches being an option, and I don't understand them very well yet, but I think that would require me to make a decision method based on the outcome of this test, and send that outcome to the switch; which wouldn't be ideal, as I could simply have two if statements and less code.
Is there any way to do this in one statement? It's not necessary for this specific program, but I want to know for the future.
Thanks!

I am assuming that you started with this code:
if (input == string.Empty)
{
MessageBox.Show("Nothing to encrypt!");
return null;
}
if (typeComboBox.Text == null)
{
MessageBox.Show("Nothing Selected!");
return null;
}
I don't consider there to be anything wrong with this code at all, and this is probably the most readable. It will perform exactly as many tests as necessary, and no more. Any alternative will result in more tests being performed, even though you may wind up with less code. For example:
if (input == string.Empty || typeComboBox.Text == null)
{
MessageBox.Show((input == string.Empty) ? "Nothing to encrypt!" : "Nothing Selected!");
return null;
}
Less lines of code, but in a failure scenario there will be two or three tests performed instead of one or two. It's also a bit less straightforward.
Terse code is nice, but make it too terse and it becomes harder to maintain. Readability lies somewhere between verbose and terse, and in this case the more verbose code is more readable, in my opinion.
Another option is to consider the fact that it would be appropriate to report multiple errors. For that, try code like this:
List<string> errors = new List<string>();
if (input == string.Empty)
{
errors.Add("Nothing to encrypt.");
}
if (typeComboBox.Text == null)
{
errors.Add("Nothing selected.");
}
if (errors.Count != 0)
{
MessageBox.Show(string.Join(" ", errors.ToArray()));
return null;
}
This is a bit more verbose than your original code, but it will allow all relevant errors to be reported instead of only the first one encountered.

#millimoose's comment is right on; two if statements would be the cleanest thing for your code. However, if you're wanting to expand your validations to a large number or establish a general pattern for validations of this sort, you could do something like set up a validation table:
public class ValidationRule
{
public ValidationRule(Func<bool> test, string errorMessage)
{
this.Test = test;
this.ErrorMessage = errorMessage;
}
public Func<bool> Test { get; private set; }
public string ErrorMessage { get; private set; }
}
var validationRules = new[] {
new ValidationRule(() => input != string.Empty, "Nothing to encrypt!"),
new ValidationRule(() => typeComboBox.Text != null, "Nothing Selected!")
};
With a table like this, you could then have code like this:
var errors = validationRules.Where(r => !r.Test()).Select(r => r.ErrorMessage);
if (errors.Any())
{
MessageBox.Show(string.Join(' ', errors));
return null;
}
If, however, you're only looking for something for your two conditions, then this is over-engineering.

I'd suggest a slightly different pattern that might be more readable:
StringBuilder message = new StringBuilder();
if (input == string.Empty) message.Append("Nothing to encrypt!\n");
if (typeComboBox.Text == null) message.Append("Nothing selected!\n");
// ... repeat as many times as desired ...
if (message.Length > 0) {
MessageBox.Show(message);
return null;
} else {
// proceed with your code here
}
This code has the advantage that it can show multiple messages, if more than one is valid. It can be frustrating for a user to see only one message at a time, if they have to go back, fix something, hit submit, and see a different error message.

There isn't a way in code to have three (seemingly) different actions decided by a single logical statement. If you try to break it down to the simplest logical (not in code, but just mental logic) flow you still end up with something like:
If A is true then do B
If C is true then do D
If both A and C is true do B and D
That can be simplified by noting (as you did) that each condition is actually separate from the other:
If A is true then B is always done
If C is true then D is always done
So, in your code, the simplest breakdown is
if (input == string.empty)
{
// Do some stuff
}
if (typeComboBox.Text == null)
{
// Do some other stuff
}
Now, rather than have a long complicated set of instructions on either method - you can simplify the look of your code by making this simply a decision section, that calls other methods to do the work:
if (input == string.empty)
{
this.PrimeInputs(); // or something
}
if (typeComboBox.Text == null)
{
this.InitTextBoxes(); // or something
}
The main thing is, this is different than a logical AND and logical OR since you want one action or the other - in some cases, and neither action if both cases are false, and both actions if both cases are true.

I wouldn't say this is better than a couple "if" statements, but it is only one.
var message =
((input==string.Empty ?
"Nothing to encrypt! " :
"") +
(typeComboBox.Text == null ?
"Nothing Selected!" :
"")).Trim();
if (message != "") {
MessageBox.Show(message);
return null;
}
Generally speaking, though, I like using conditional operators to construct logic trees that result in a single outcome, it's much more terse than a bunch of nested if/else clauses. As long as you indent properly I find such structures highly readable and expressive. Unfortunately in this case it's not ideal because you have outcomes that depend on combinations of your operands. Using this kind of logic to build a string probably isn't the best idea, though it is still probably the most terse option.

Related

Nested if-conditions vs multiple separated if-conditions with return statement in each one

What is the most professional code-style in the below two functions ?
And what if the function become more complex & larger such as to have 20 checks ?
Note: i need to do some stuff after each check, so i can't concatenate all in one if-statement like:
if (vehicle.isBus) && (vehicle.numberOfWheels == 6) && (vehicle.motorVersion == 2019)
//first alternative
public bool validate(Vehicle vehicle)
{
if(vehicle.isBus)
{
//do some stuff here related to vehicle.isBus
if (vehicle.numberOfWheels == 6)
{
//do some stuff here related to vehicle.numberOfWheels
if (vehicle.motorVersion == 2019)
{
//do some stuff here related to vehicle.motorVersion
return true;
}
}
}
return false;
}
//second alternative
public bool validate(Vehicle vehicle)
{
if (!vehicle.isBus)
{
return false;
}
//do some stuff here related to vehicle.isBus
if (vehicle.numberOfWheels != 6)
{
return false;
}
//do some stuff here related to vehicle.numberOfWheels
if (vehicle.motorVersion != 2019)
{
return false;
}
//do some stuff here related to vehicle.motorVersion
return true;
}
One golden rule I follow is to Avoid Nesting as much as I can.
Use the one that makes the code more readable and understandable. For just two conditions, the first way is more logical and readable. It might not be the case anymore with 5 or 6 conditions linked with &&, || and !.
So when the number of checks are 5+ then you should prefer second alternative.
Note : Multiple ifs without each calling return implies that 2 or more ifs could be true.
The second example should require less cognitive overhead while reading the code.
In the first example, you need to keep a mental "stack" of the program state. In the second example, you just need to keep a list of things that you already know to be true.
The second example is also less likely to be confounded by a misplaced brace; in fact it doesn't require any braces at all in this example.

Is there a more readable way of making a long chain of && statements?

Suppose I have a long, complex list of conditions, which must be true in order for an if statement to run.
if(this == that && foo != bar && foo != that && pins != needles && apples != oranges)
{
DoSomethingInteresting();
}
Typically, if I'm forced into doing something like this, I'll just put each statement on its own line, like this:
if
(
this == that
&& foo != bar
&& foo != that
&& pins != needles
&& apples != oranges
)
{
DoSomethingInteresting();
}
But I still feel this is a bit of a mess. I'm tempted to refactor the contents of the if statement into its own property like this
if(canDoSomethingInteresting)
{
DoSomethingInteresting();
}
But then that just moves all the mess into canDoSomethingInteresting() and doesn't really fix the problem.
As I said, my goto solution is the middle one, because it doesn't obfuscate the logic like the last one and is more readable than the first. But there must be a better way!
Example in response to Sylon's comment
bool canDoSomethingInteresting
{
get{
//If these were real values, we could be more descriptive ;)
bool thisIsThat = this == that;
bool fooIsntBar = foo != bar;
bool fooIsntThat = foo != that;
return
(
thisIsThat
&& fooIsntBar
&& fooIsntThat
);
}
}
if(canDoSomethingInteresting)
{
DoSomethingInteresting();
}
In my opinion moving the mess into a Property or a Method is not that bad an idea. That way it is self contained and your main logic where you do the if(..) check becomes more readable. Especially if the list of conditions to check is huge, it is better off being in a property, that way if you need to re-use that you are not duplicating that check.
if(IsAllowed)
{
DoSomethingInteresting();
}
Containing the code for the different conditions in separate vars is a great way to go for readability and maintainability. When your vars are named good you get
if (goToNextPage)
{
if (notAdmin)
{
RedirectToNormalPage();
}
else
{
RedirectToAdminPage();
}
}
Compared to something like this
if ((x == 1) && ((y == 'r') || (y == 't')))
{
if (!a)
{
RedirectToNormalPage();
}
else
{
RedirectToAdminPage();
}
}
I will let you choose which one you would want to read when you go back to your code at a later date.
Method is good. Better method name would tell what it tests, not what can be done if it is true. Like
if (isFooValid()) { mergeFoo(); }
If it fits logically to the code flow and especially if I don't care if it is done or not at that point, I also often wrap whole if to a method:
maybeMergeFoo();
The key is to mentally step back and look what fits best to the current code, and to the code you are going to write next. Often it is then clear what is the right way to organize the code.

Is it good practice use more that one RETURN statement in a method? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is it good practice to return at the end of a method
I would like to know if could be considered good practice use several RETURN statements in a method and why.
If not, I would like to know how you would rewrite the code in a different way.
public string GetNominativeById(int? candidateId)
{
if (candidateId.HasValue)
return repepositoryCandidate.GetById(candidateId.Value).Nominative;
else
return string.Empty;
}
}
With one RETURN
public string GetNominativeById(int? candidateId)
{
string result;
if (candidateId.HasValue)
result = repepositoryCandidate.GetById(candidateId.Value).Nominative;
else
result = string.Empty;
return result;
}
}
You don't actually need else
string GetNominativeById(int? candidateId)
{
if (!candidateId.HasValue)
return string.Empty;
return repepositoryCandidate.GetById(candidateId.Value).Nominative;
}
Consider this anti arrow pattern:
if (condition1)
{
if (condition2)
{
if (condition3)
{
// code lines
}
}
}
the way to return immediately will make your code more readable:
if (!condition1) return;
if (!condition2) return;
if (!condition3) return;
// code lines
No, it's considered bad practice not so good practice to have multiple exit points in a method. It's easier to follow the code if there is a single point of exit.
However, when the method is as small as in the example, it's not hard to follow the code anyway, so having multiple exit points is not really a problem. If it makes the code simpler, you can very well use multiple return statements.
Although you should strive to have only one return statement for readability purposes the are several patterns that involve multiple return statements. One example is Guard Clause.
Example of guard clause:
public Foo merge (Foo a, Foo b) {
if (a == null) return b;
if (b == null) return a;
// complicated merge code goes here.
}
Some style guides would have us write this with a single return as follows
public Foo merge (Foo a, Foo b) {
Foo result;
if (a != null) {
if (b != null) {
// complicated merge code goes here.
} else {
result = a;
}
} else {
result = b;
}
return result;
}
Another case is a switch statement when you might want to return from each case:
switch(foo)
{
case "A":
return "Foo";
case "B":
return "Bar";
default:
throw new NotSupportedException();
}
I would rewrite your code as:
public string GetNominativeById(int? candidateId)
{
return candidateId.HasValue
? repepositoryCandidate.GetById(candidateId.Value).Nominative;
: string.Empty;
}
At the end of the day, remember that you (and other developers) will be reading your code many times, so make sure that it's readable and obvious.
Take a look at the following Article on Wikipedia. What you're asking is whether you should follow the SESE (single entry, single exit) principle from structured programming.
One of the rules of Structured programming states that each method should have a single entry and exit point. Having a single exit point (return statement in this case) means any clean up, such as calling Close or Dispose, only needs to happen once. The impact of having multiple exit points is minor on small methods but increases as method complexity increases, where it may be easy to miss a case, or as code as refactored or modified.
there is nothing wrong with having more return statement, sometimes it actually help you minify your code and save some unnecessary variable assign like what Cuong Le did pointed out. :D
make it a habit to add return at the end of the method, so you will have to close any active objects (if you have)
public string GetNominativeById(int? candidateId)
{
string _returnValue = string.Empty;
if (candidateId.HasValue)
_returnValue repepositoryCandidate.GetById(candidateId.Value).Nominative;
else
_returnValue = string.Empty;
return _returnValue;
}
side-note: Ternary Operator is not really an answer on this (I think) because there are some case that you multiple code blocks in your IF statement.
All this depends on
coding standard you use with other developers
and actual code readability (so personal perception of the code)
In general, when if/else becomes too much, I use return instead.
So instead of using:
if(...)
{
if(...)
{
if(...)
{
}
}
else if(...)
{
}
..
else
{
}
}
use a return:
if(!...)
return;
if(!...)
return;
you actually can not use more than one return statement in a single method, what you did in your code, you used a if else statement, so only one will be executed anyway. Your code seems good to me.
Yes if it is necessary then why not use several return statements. There will be no issue with the performance.
To rewrite this code:
public string GetNominativeById(int? candidateId)
{
if (candidateId.HasValue)
return repepositoryCandidate.GetById(candidateId.Value).Nominative;
return string.empty;
}
OR use "ternary operator".
public string GetNominativeById(int? candidateId)
{
return candidateId.HasValue ? repepositoryCandidate.GetById(candidateId.Value).Nominative : string.Empty;
}
Why not? But you don't need else.
public string GetNominativeById(int? candidateId)
{
if (candidateId.HasValue)
return repepositoryCandidate.GetById(candidateId.Value).Nominative;
return string.Empty;
}

Is it acceptable to only use the 'else' portion of an 'if-else' statement?

Sometimes, I feel like it is easier to check if all of the conditions are true, but then only handle the "other" situation.
I guess I sometimes feel that it is easier to know that something is valid, and assume all other cases are not valid.
For example, let's say that we only really care about when there is something wrong:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop)))
{
// All the conditions passed, but we don't actually do anything
}
else
{
// Do my stuff here, like error handling
}
Or should I just change that to be:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop)))
{
// Do my stuff here, like error handling
}
Or (which I find ugly):
object value = GetValueFromSomeAPIOrOtherMethod();
if(!((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop))))
{
// Do my stuff here, like error handling
}
Though rare for me, I sometimes feel that writing in this form leads to the clearest code in some cases. Go for the form that provides the most clarity. The compiler won't care, and should generate essentially (probably exactly) the same code.
It may be clearer, though, to define a boolean variable that is assigned the condition in the if () statement, then write your code as a negation of that variable:
bool myCondition = (....);
if (!myCondition)
{
...
}
Having an empty if block with statements in the else is ... just bad style. Sorry, this is one of my pet peeves. There is nothing functionally wrong with it, it just makes my eyes bleed.
Simply ! out the if statement and put your code there. IMHO it reduces the noise and makes the code more readable.
I should preface this by saying that it's my own personal preference, but I find myself usually pulling the validation logic out of the code and into its own validate function. At that point, your code becomes much "neater" by just saying:
if(!ValidateAPIValue(value))
That, in my mind, seems a lot more concise and understandable.
Just using the else part isn't acceptable. You needn't go to the trouble of applying De-Morgan's rule, just not the whole expresssion. That is, go from if (cond) to if (!(cond)).
I think it's completely unacceptable.
The only reason at all would be to avoid a single negation and pair of parentheses around the expression. I agree that the expressions in your example are horrible, but they are unacceptably convoluted to begin with! Divide the expression into parts of acceptable clarity, store those into booleans (or make methods out of them), and combine those to make your if-statement condition.
One similar design I do often use is exiting early. I don't write code like this:
if (validityCheck1)
{
if (validityCheck2)
{
// Do lots and lots of things
}
else
{
// Throw some exception, return something, or do some other simple cleanup/logic (version 2)
}
}
else
{
// Throw some exception, return something, or do some other simple cleanup/logic. (version 1)
}
Instead I write this:
if (!validityCheck1)
{
// Throw some exception, return false, or do some other simple logic. (version 1)
}
if (!validityCheck2)
{
// Throw some exception, return false, or do some other simple logic. (version 2)
}
// Do lots and lots of things
This has two advantages:
Only a few input cases are invalid, and they have simple handling. They should be handled immediately so we can throw them out of our mental model as soon as possible and fully concentrate on the important logic. Especially when there are multiple validity checks in nested if-statements.
The block of code that handles the valid cases will usually be the largest part of the method and contain nested blocks of its own. It's a lot less cluttered if this block of code is not itself nested (possibly multiple times) in an if-statement.
So the code is more readable and easier to reason about.
Extract your conditions, then call
if(!ConditionsMetFor(value))
{
//Do Something
}
Although this is not always practical, I usually prefer to change
if (complexcondition){} else {/*stuff*/}
to
if (complexcondition) continue;
/*stuff*/
(or break out with return, break, etc.). Of course if the condition is too complex, you can replace it with several conditions, all of which cause the code to break out of what it is doing. This mostly applies to validation and error-checking types of code, where you probably want to get out if something goes wrong.
If I see an "if", I expect it to do something.
if(!condition)
is far more readable.
if(condition) {
//do nothing
}
else {
//do stuff
}
essentially reads, "If my condition is met, do nothing, otherwise do something."
If we are to read your code as prose (which good, self-documenting code should be able to be read in that fashion) that's simply too wordy and introduces more concepts than necessary to accomplish your goal. Stick with the "!".
This is bad style, consider some very useful alternatives:
Use a guard clause style:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop)))
{
return;
}
// do stuff here
Extract the conditional into its own method, this keeps things logical and easy to read:
bool ValueHasProperty(object value)
{
return (value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop));
}
void SomeMethod()
{
object value = GetValueFromSomeAPIOrOtherMethod();
if(!ValueHasProperty(value))
{
// do stuff here
}
}
Your question is similar to my answer(simplifying the conditions) on favorite programmer ignorance pet peeve's
For languages that don't support an until construct, chaining multiple NOTs makes our eyes bleed
Which one is easier to read?
This:
while (keypress != escape_key && keypress != alt_f4_key && keypress != ctrl_w_key)
Or this:
until (keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key)
I am of the opinion that the latter is way easier to grok than the first one. The first one involves far too many NOTs and AND conditions makes the logic more sticky, it forces you to read the entire expression before you can be sure that your code is indeed correct, and it will be far more harder to read if your logic involves complex logic (entails chaining more ANDs, very sticky).
During college, De Morgan theorem is taught in our class. I really appreciate that logics can be simplified using his theorem. So for language construct that doesn't support until statement, use this:
while !(keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key)
But since C don't support parenthesis-less while/if statement, we need to add parenthesis on our DeMorgan'd code:
while (!(keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key))
And that's what could have prompted Dan C's comment that the DeMorgan'd code hurts his eyes more on my answer on favorite programmer ignorance pet peeve's
But really, the DeMorgan'd code is way easier to read than having multiple NOTS and sticky ANDs
[EDIT]
Your code (the DeMorgan'd one):
object value = GetValueFromSomeAPIOrOtherMethod();
if ( value == null || string.IsNullOrEmpty(value.Prop)
|| !possibleValues.Contains(value.prop) )
{
// Do my stuff here, like error handling
}
..is perfectly fine. In fact, that's what most programmers(especially from languages that don't have try/catch/finally constructs from the get-go) do to make sure that conditions are met(e.g. no using of null pointers, has proper values, etc) before continuing with the operations.
Note: I took the liberty of removing superfluous parenthesis on your code, maybe you came from Delphi/Pascal language.
I do it when my brain can easily wrap itself around the logic of the success but it is cumbersome to understand the logic of the failure.
I usually just put a comment "// no op" so people know it isn't a mistake.
This is not a good practice. If you were using ruby you'd do:
unless condition
do something
end
If your language doesn't allow that, instead of doing
if(a){}else{something}
do
if(!a){something}
I find it to be unacceptable (even though I'm sure I've done it in the past) to have an empty block like that. It implies that something should be done.
I see the other questions state that it's more readable the second way. Personally, I say neither of your examples is particularly readable. The examples you provided are begging for an "IsValueValid(...)" method.
I occasionally find myself in a related but slightly different situation:
if ( TheMainThingIsNormal () )
; // nothing special to do
else if ( SomethingElseIsSpecial () ) // only possible/meaningful if ! TheMainThingIsNormal ()
DoSomethingSpecial ();
else if ( TheOtherThingIsSpecial () )
DoSomethingElseSpecial ();
else // ... you see where I'm going here
// and then finish up
The only way to take out the empty block is to create more nesting:
if ( ! TheMainThingIsNormal () )
{
if ( SomethingElseIsSpecial () )
DoSomethingSpecial ();
else if ( TheOtherThingIsSpecial () )
DoSomethingElseSpecial ();
else // ...
}
I'm not checking for exception or validation conditions -- I'm just taking care of special or one-off cases -- so I can't just bail out early.
My answer would usually be no....but i think good programming style is based on consistency.....
so if i have a lot of expressions that look like
if (condition)
{
// do something
}
else
{
// do something else
}
Then an occasional "empty" if block is fine e.g.
if (condition)
{ } // do nothing
else
{
// do something else
}
The reason for this is that if your eyes sees something several times, their less likely to notice a change e.g. a tiny "!". So even though its a bad thing to do in isolation, its far likely to make someone maintaining the code in future realize that this particular if..else... is different from the rest...
The other specific scenerio where it might be acceptable is for some kind of state machine logic e.g.
if (!step1done)
{} // do nothing, but we might decide to put something in here later
else if (!step2done)
{
// do stuff here
}
else if (!step3done)
{
// do stuff here
}
This is clearly highlighting the sequential flow of the states, the steps performed at each (even if its nothing). Id prefer it over something like...
if (step1done && !step2Done)
{
// do stuff here
}
if (step1done && step2done && !state3Done)
{
// do stuff here
}
I like the second version. It makes code more clean. Actually this is one of the things I would ask to correct during the code review.
I always try and refactor out big conditions like this into a property or method, for readability. So this:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop)))
{
// Do my stuff here, like error handling
}
becomes something like this:
object value = GetValueFromSomeAPIOrOtherMethod();
if (IsValueUnacceptable(value))
{
// Do my stuff here, like error handling
}
...
/// <summary>
/// Determines if the value is acceptable.
/// </summary>
/// <param name="value">The value to criticize.</param>
private bool IsValueUnacceptable(object value)
{
return (value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop))
}
Now you can always reuse the method/property if needed, and you don't have to think too much in the consuming method.
Of course, IsValueUnacceptable would probably be a more specific name.
1st:
object value = GetValueFromSomeAPIOrOtherMethod();
var isValidValue = (value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop));
if(!isValidValue)
{
// Do my stuff here, like error handling
}
2cnd:
object value = GetValueFromSomeAPIOrOtherMethod();
if(!isValidAPIValue(value))
{
// Do my stuff here, like error handling
}
Are all the expressions really the same? In languages that support short-circuiting, making the change between ands and ors can be fatal. Remember &&'s use as a guard to prevent the other conditions from even being checked.
Be careful when converting. There are more mistakes made than you would expect.
In these cases you may wish to abstract the validation logic into the class itself to help un-clutter your application code.
For example
class MyClass
{
public string Prop{ get; set; }
// ... snip ...
public bool IsValid
{
bool valid = false;
if((value != null) &&
(!string.IsNullOrEmpty(value.Prop)) &&
(possibleValues.Contains(value.prop)))
{
valid = true
}
return valid;
}
// ...snip...
}
Now your application code
MyClass = value = GetValueFromSomewhere();
if( value.IsValie == false )
{
// Handle bad case here...
}
I'm a fan of DeMorgan's Rule which takes your ex3 and produces your ex2. An empty if block is a mental block imo. You have to stop to read the nothing that exists - then you have to wonder why.
If you have to leave comments like // This left blank on purpose; then the code isn't very self-explanatory.
The style that follow to have one block empty of if-else is considered as a bad style..
for good programming practice if you dont have to write in if block you need to put (!) 'Not' in if block ..no need to write else
If(condition)
//blank
else
//code
can be replaced as
if(!condition)
//code
this is a saving of extra line of code also..
I wouldn't do this in C#. But I do it in Python, because Python has a keyword that means "don't do anything":
if primary_condition:
pass
elif secondary_condition1:
do_one_thing()
elif secondary_condition2:
do_another_thing()
You could say that { } is functionally equivalent to pass, which it is. But it's not (to humans) semantically equivalent. pass means "do nothing," while to me, { } typically means "there used to be code here and now there isn't."
But in general, if I get to the point where it's even an issue whether sticking a ! in front of a condition makes it harder to read, I've got a problem. If I find myself writing code like this:
while (keypress != escape_key && keypress != alt_f4_key && keypress != ctrl_w_key)
it's pretty clear to me that what I'm actually going to want over the long term is more like this:
var activeKeys = new[] { escape_key, alt_f4_key, ctrl_w_key };
while (!activeKeys.Contains(keypress))
because that makes explicit a concept ("these keys are active") that's only implicit in the preceding code, and makes the logic "this is what you happens when an inactive key is pressed" instead of "this is what happens when a key that's not one ESC, ALT+F4 or CTRL+W is pressed."

C# Code Simplification Query: The Null Container and the Foreach Loop

I frequently have code that looks something like this:
if (itm != null)
{
foreach (type x in itm.subItems())
{
//dostuff
}
}
//do more stuff
In situations where //do more stuff is omitted, it is very easy to avoid the extra foreach loop. By exitting scope using the appropriate command (depending on what is going on, this generally would mean a return statement or a continue statement).
This type of thing tends to result in arrow code. I currently have a few ways to deal with this:
Use code like itm = itm == null ? itm.subItems() : emptyArray
Allow arrow code
Use goto
Use evil scoping hacks (wrapping the whole thing, if statement in all, in a scope and then breaking out of it). In my opinion evil scoping hacks are basically equivalent to goto except uglier and harder to read, so I don't consider this a valid solution.
Refactor some of the chunks into new methods. There are in fact a few cases where this probably is a good solution, but mostly it's not appropriate since the null references are mainly error conditions from MS-functions.
Anyone care to offer a response on what approaches are considered preferable?
If you're using C# 3, you could always write an extension method:
public static IEnumerable<SubItem> SafeSubItems(this ItemType item)
{
return item == null ? Enumerable.Empty<SubItem> : source.SubItems();
}
Then just write:
foreach (SubItem x in itm.SafeSubItems())
{
// do stuff
}
// do more stuff
The key thing is that extension methods can be called even "on" null references.
What would be nice would be a "null-safe dereferencing" operator, so we could write:
// Not valid C# code!
foreach (SubItem x in itm?.SubItems() ?? Enumerable.Empty<SubItem>())
{
}
Or just define an EmptyIfNull extension method on IEnumerable<T> and use
// Not valid C# code!
foreach (SubItem x in (itm?.SubItems()).EmptyIfNull())
{
}
You could use the Coalesce operator (coded as a double question mark, ??, .net 2 upwards). This'll return the first non-null value in a list of values, so in this snippet...
MyClass o1 = null;
MyClass o2 = new MyClass ();
MyClass o3 = null;
return o1 ?? o2 ?? o3;
...o2 would be returned.
So you could re-code your original code sample as
foreach (type x in (itm ?? emptyArray).subItems())
{
//dostuff
}
//do more stuff
However, personally I don't mind the nesting. It's instantly clear what's going on. I find the Coalesce operator a little harder to read, and that little nest is a small price to pay for clarity.
I like less nesting, for me it reads better. No goto please :)
I keep methods short, so it is usually a return for that scenario.
if (itm == null) return;
foreach (type x in itm.subItems())
{
//dostuff
}
If the more stuff is needed, are simple statements and can be done before the foreach, you can:
if (itm == null)
{
//do more stuff
return;
}
foreach (type x in itm.subItems())
{
//dostuff
}
If the above is not the case, it is likely the method is too long and some of it would be moved away anyway. Probably:
if( itm != null ) SomeActionOnSubItems(itm.subItems);
// do more stuff (can be some method calls depending on level of abstraction).
Personally, I'd probably leave the structure the way you have it.
The first option (itm = itm == null ? itm.subItems() : emptyArray) seems less nasty than the others, but I still like your original better.
The problem is, from another developer's perspective, anything else is going to make your code less obvious. If there is a foreach running through a collection, I expect that the collection will (at least normally) have items contained in there. If the collection could be empty, that's not going to be obvious to other people without comments (which take longer to write than the if check).
Doing any of the hacks to avoid the if check just seems like you're trying to be too clever.

Categories

Resources