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

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.

Related

Looping inside a if block

The following is common in any programming language.
foreach(.....)
{
if(...)
....
}
I wonder whether it is a good programming practice to use the following. I know it works, but it looks little bit untidy.
if(....)
{
foreach(...)
{
...
}
}
Iterating over a collection when some condition evaluates to true is the requirement. But I have never seen this in any kind of sample codes. In a nutshell, I have never noticed such in codes written by other people. But this works and gives me what I want. But I want to avoid writing a loop inside a if block.
Can someone point out an alternative to this ?
Either is perfectly fine, but of course you should use only the construct that works.
An if statement inside a foreach loop is often checking some property of each element being enumerated. In this case, you cannot swap the order of the statements, because you need to execute the if for each element.
For example:
foreach (Foo foo in fooCollection)
{
if (foo.Name == "ignore me")
{
continue;
}
Console.WriteLine(foo.Name);
}
On the other hand, it would be wasteful to check inside a loop a condition that is "invariant" for the loop. That is, one that always has the same result.
For example:
bool ignoreAllFoos = true;
foreach (Foo foo in fooCollection)
{
if (ignoreAllFoos)
{
continue;
}
Console.WriteLine(foo.Name);
}
That would (normally) be useless and inefficient. Why enumerate all of the elements if you're never going to process any of them? So in that case, you could (and should) put the foreach inside the if:
bool ignoreAllFoos = true;
if (!ignoreAllFoos)
{
foreach (Foo foo in fooCollection)
{
Console.WriteLine(foo.Name);
}
}
Of course, the above examples are completely contrived. But I hope that they illustrate the difference between having the if inside the foreach loop vs having the foreach loop inside the if. The two ways of writing the code really do not do the same thing, but they are both useful ways of writing code. It just depends on what behavior you actually want to have.

Inline HashSet<> declaration vs static attribute, .Contains() performance

In order to use the Contains method, what is better (is any difference), declare a static fieldwith the HashSet or declare it inline (new HashSet { SomeEnum.SomeValue1, SomeEnum.SomeValue2, ... }.Contains(SomeEnum.SomeValue1))
I ask that because in some cases I only going mto use the hashset once, and for me is better to have it on the code and not in some static attribute
Example inline (What I wanna use):
public void Validate(Type type) {
if(!new HashSet<Type> { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 }.Contains(type)) {
//do something
}
if(new HashSet<Type> { Type.TYPE_2, Type.TYPE_3, Type.TYPE_4, Type.TYPE_5 }.Contains(type)) {
//do something
}
}
Example static (What I prefer not to use):
private static HashSet<Type> _values1 = new HashSet<Type> { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 };
private static HashSet<Type> _values2 = new HashSet<Type> { Type.TYPE_2, Type.TYPE_3, Type.TYPE_4, Type.TYPE_5 };
public void Validate(Type type) {
if(!_values1.Contains(type)) {
//do something
}
if(_values2.Contains(type)) {
//do something
}
}
Example using logical expressions (What I don't want to use):
public void Validate(Type type) {
if(type != Type.TYPE_1 && type != Type.TYPE_2 && type != Type.TYPE_3 && type != Type.TYPE_4) {
//do something
}
if(type == Type.TYPE_2 || type == Type.TYPE_3 || type == Type.TYPE_4 || type == Type.TYPE_5) {
//do something
}
}
If you have not identified this as a bottleneck through performance testing, the the "right" way is just to use code that makes the most sense to people reading it. That's somewhat subjective, so there may not be a "right" way, but any approach that's not easy to understand will be the "wrong" way.
I would probably just use an inline-declared array, unless the list of values is reusable in other methods, or it's so long that it gets in the way of reading what the method is trying to do.
public void Validate(Type type) {
if(!new[] { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 }.Contains(type)) {
//do something
}
}
If you have identified this as a definite performance bottleneck (meaning you're probably doing this check millions of times per second, then you'll probably want to do performance testing on a few different approaches, because the correct answer depends on how many items are in the set you're trying to match against.
Besides the approaches you've suggested, here are a couple of other possibilities that will probably be faster (but again, you'd need to test them to make sure:
Flags Enum
It looks like you're using enum values. If that enum type has a small number of potential values, you could make it into a flags enum and then use bitwise logic to determine in a single CPU operation whether the given value matches any of the values you're looking for.
[Flags]
public enum Type
{
TYPE_1 = 1,
TYPE_2 = 1<<1,
TYPE_3 = 1<<2,
TYPE_4 = 1<<3,
TYPE_5 = 1<<4,
// etc...
}
Usage:
const Type toMatch = (Type.TYPE_1 | Type.TYPE_2 | Type.TYPE_3 | Type.TYPE_4);
if((type & toMatch) == 0)
{
// do something
}
Switch statement
The compiler is really good at figuring out what will be the fastest approach, so if you use a switch statement it can decide whether to compile that to a series of if/else checks, a HashSet-style approach, or a jump table, depending on the number and values of items you're trying to check.
switch(type)
{
case Type.TYPE_1:
case Type.TYPE_2:
case Type.TYPE_3:
case Type.TYPE_4:
break;
default:
// do something
break;
}
If no new items are going to be added then your static method is the correct way to do it
private static HashSet<Type> _values = new HashSet<Type> { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 };
public void Validate(Type type) {
if(!_values.Contains(type)) {
//do something
}
}
All collections in the System.Collections namespace are thread safe for read only operations so this is a perfectly acceptable way to do it.
If you did it your "preferred" way it would still work, however you would be re-creating the collection every time you call the function and that is a unnecessary overhead that would definitely hurt performance.
Keeping with the "infrequent" or "once" usage of the lookup in mind, as hinted by the post..
If the lookup is used only within the single method then I would use an inline approach, however I would us an array (and I actually do quite often). I may or may may not use an intermediate (local) variable, depending on if I it makes the code more clear or easy to adapt in the future.
I wouldn't use a static (or even instance) variable because:
The sequence is not shared in this case;
The of trivial amount of resources to create the object (especially for an array) is minimal;
The GC is really good with short-lived objects .. and, more importantly, there is no need to extend the lifetime
If I wanted to share this lookup across several methods, I would look into creating a getter that returned a new object (which covers #2 and #3 above while meeting the new requirement). With a local variable, individual methods would only create one new lookup per invocation.
I generally use an array because:
The syntax is marginally simpler (the type can be inferred and omitted);
The array (especially the construction) is more lightweight than a HashSet, yet provides the required lookup functionality;
Searching a small array is likely fast enough (as there is a very small n)
I would not use various long-hand forms if it makes the particular code harder to follow. The task is "contains", not some more complex conditional logic.
Unless there is an actual performance problem, do it a clean and simple way and move on with more interesting tasks.

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

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.

Simplify if(x == 1 || x == 2) [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C# if statements matching multiple values
I often find myself writing code where a variable can be either A or B, for example when I call OnItemDataBound on a repeater:
protected void repeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{}
}
I then often think, there must be a simpler way of doing this. I would like to write something like:
if(x == (1 || 2))
SQL has the IN(..) operator, is there something similar in C#?
WHERE x IN(1,2)
I know I could use a switch-statement instead, but thats not simple enought. I want it to be done in an If statement, if possible.
I think it is fine as-is; however, you could do something like:
// note the array is actually mutable... just... don't change the contents ;p
static readonly ListItemType[] specialTypes =
new[]{ListItemType.Item, ListItemType.AlternatingItem};
and check against:
if(specialTypes.Contains(e.Item.ItemType)) {
// do stuff
}
But to emphasise: I'd actually just use a switch here, as switch on integers and enums has special IL handling via jump-tables, making it very efficient:
switch(e.Item.ItemType) {
case ListItemType.Item:
case ListItemType.AlternatingItem:
// do stuff
break;
}
You could write an extension method like this:
public static bool In<T>(this T x, params T[] values)
{
return values.Contains(x);
}
And call it like this:
1.In(2,3,4)
But I would say it's not worth the effort.
If you want to mimic the SQL IN statement you could do something like this...for the simple case of having 2 items, this probably isn't simpler, but for more items, it certainly would be.
(new[] { 1, 2 }).Contains(x);
You can use the following Method, found in this Answer
public static bool In<T>(this T source, params T[] list)
{
if(null==source) throw new ArgumentNullException("source");
return list.Contains(source);
}
Call like this:
if(x.In(1,2,4))
{
// ...
}
Unless there is no too much possible options for single if, your code is readable and clear, which is most important.
If you often meet if with more the 3 condition, you can use
new List<..>{ condition1, condition2, ... ConditionN}.Any<>().
Something like that.
I think that is as simple as you are going to get. Notice how the other answers or even your own suggestion actually use special constructs and workarounds just to shorten some trivial bit of syntax. Also, these clever workarounds will hinder performance.
But, for two to three items that use a lot of space, I like to put the conditions on subsequent lines to make the reading a bit easier.
if (x == MyEnum.SomeReallyLongNameThatEatsUpTheLine ||
x == MyEnum.TheOtherNameThatWastesSpace)
{
// The simplest code.
}
I guess if you had a very long list of possible values the array approach is much better.

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."

Categories

Resources