while() without {}? - c#

I had this code in a project in VS2010 - it was a placeholder method I hadn't fully implemented yet. I started the implementation today. Notice there are no {} surrounding the if/else for the while statement. This compiled many times - it has been that way for quite some time. Is this a bug in VS? I thought loops all needed {}
private void ParsefCIPProfiles(string block)
{
StringReader reader = new StringReader(block);
string readline = reader.readline();
while (readline != null)
if ()
{}
else
{}
}

No, it isn't a bug. In fact for single-statement contents, most other scoped statements also don't require the curly braces. For instance:
//This is valid
using (var f = new foo)
f.Bar();
// So is this
foreach (var i in someInts)
Console.Out.WriteLine(i);

Only if there is more than one statement and you want all of those statements to be part of the loop.
Here there is only one if...else statement and that is part of the loop. Anything after that will not be part of the loop and if you want more statements, enclose them in {..}
This is the case with for, if, etc.

See the C# formal grammar: http://msdn.microsoft.com/en-us/library/aa664812(v=vs.71).aspx
while-statement:
while ( boolean-expression ) embedded-statement
embedded-statement:
block
empty-statement
expression-statement
selection-statement
iteration-statement
jump-statement
try-statement
checked-statement
unchecked-statement
lock-statement
using-statement
selection-statement:
if-statement
switch-statement
if-statement:
if ( boolean-expression ) embedded-statement
if ( boolean-expression ) embedded-statement else embedded-statement
The important thing to note is that a while-statement requires an embedded-statement, and an if-statement is a selection-statement which is an embedded-statement.
You can derive your sample code with these productions.

You can omit braces when there is just one statement contained in the loop. Or in an if/else statement.

Curly braces aren't usually necessary if there is only one statement following, for example:
if(readline != 0)
doSomething();
Should work because the function doSomething() is in the if loop's scope. However, what I would expect this code to look like if there WERE curly braces (to identify scope boundaries):
while (readline != null) {
if ()
{ }
}
else
{}
NOW the else is not in the scope of the while loop, and I don't see a reason why it wouldn't compile. It just might not behave as you imagine it should.
However, the above code is not quite correct. It does not perfectly mimic your code. If-else statements are considered one statement. Therefore, the scope boundaries are actually looking like:
while (readline != null) {
if ()
{ }
else
{}
}
Edit: Scope is the context in which an identifier can be used. So, the scope of a variable depends on how it is defined and where. That means the variable can only be used in certain places. The scope of a loop is everything within its curly braces; if it doesn't have curly braces, then only the next statement is within the loop's scope.
This code will work:
while(readline != null)
if(readline == 1)
doSomething();
That code works because doSomething() is in the scope of the if statement which is also in the scope of the while loop.

As many of the other posters here have pointed out, the braces are not necessary because the while loop contains only one statement. The if-else is considered to be a single statement even though it is split between multiple lines.
However, I always include braces around all nested statements for the following reason. Consider I have the following code:
while (readline != null)
if (foo = true)
{ DoSomething(); }
else
{ DoSomethingElse(); }
Then later I decide I want to add another statement to my while loop:
while (readline != null)
if (foo = true)
{ DoSomething(); }
else
{ DoSomethingElse(); }
DoYetAnotherThing();
Oops, see my mistake? The DoYetAnotherThing() call will be executed after the loop completes, which is not what I want, because I did not include the braces. If I had included them from the beginning, I would not have had this problem. So I think it is generally a good practice to always include them even when there is only a single statement, it helps avoid errors.
There's also confusion that can be caused by the dangling else problem when you don't use braces, but I'll stop rambling and let you do your own research into that.

There is nothing, syntactically, wrong with the following statement:
while (readline != null)
if ()
{ }
else
{ }
The if ... else is a single statement and will continue until readline is null.

while() without { } will execute the next single statement. if else constitutes a single statement so it will be executed until readline is null.

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.

a ; without statement in C#

I was looking at a code sample in C#. There is ; without any statement before it. I thought it is typo. I tried to compile with ;. It compiled fine. What is the use of ; without any code statement?
I'm using VS 2010, C# and .Net 4.0
private void CheckSmcOverride(PatLiverSmc smc)
{
;
if (smc.SmcOverride && smc.Smc != null
&& smc.Smc.Value < LiverSmcConst.SMC_OVERRIDE_POINT)
{
smc.Smc = 10;
_logger.DebugFormat("CheckSmcOverride: Override SMC {0}", smc.Smc);
}
}
A semicolon in C# is simply to denote an end-of-a-statement. Empty statements, or just a ; by itself, are valid.
You could have the following on a line by itself inside any function in C# and it should will compile fine:
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
On the same topic, but semi-different from the question at hand, is an empty set of curly-brackets, { }. These denote a "code block", but are valid just about anywhere in your code. Again, you could have something like the following on a single line and it will still compile fine:
{ } { ;;;;;;;;;; } { }
In the end, the empty-statement and empty-code blocks all compile down to "nothing to see here folks, move along" and can, in most cases, be removed from the code without consequence.
As a c# developer I use the 'empty statement'
;
(a useful case as a comment requested)
when I have a multi line lambda and I want to examine the last line of evaluation i.e.
list.ForEach(x=>
{
x.result = x.Value * x.AnotherValue;
; // otherwise I can't ever see these as you can't break on the end brace of an anonymous function
})
as a way to break point inside some code after evaluation of the line before i.e.
void SomeFunct()
{
int a = someOtherFunct();
; //I want a breakpoint here but...
//there is some huge code segment that will get skipped before I can breakpoint
}
It's a statement that does nothing. Normally this would be pointless and could just be removed, but there are times where a statement is expected and you really want nothing to happen.
Sometimes you see this with loops that cause side effects and so need no body:
int count = 0;
while(isTheRightNumber(count++))
;
Personally I dislike such code examples and discourage the practice as they tend to be harder to understand than loops that have side effect free conditions. Using a set of empty braces is a bit clearer, as is including a relevant comment, such as:
int count = 0;
while(isTheRightNumber(count++))
{ } //empty by design
Another example is the pattern of using a for loop for an infinite loop:
for(;;)
{
//stuff
}
is essentially the same as:
while(true)
{
//stuff
}
It's an empty statement. I never used it, but it exists in many languages.
semicolon(;) indicated the end of a statement. so if you just add a semicolon without anything... it means it is empty statment
An empty statement is sometimes used when a statement expects a block but you don't want it to do anything.
For example:
for(i=0; array[i]!=null; i++)
;
or for nested if then elses without braces:
// don't really do this kids
if(cond1)
if(cond2)
doit();
else
;
else
dont();
Sometimes used for 'if' clarity:
if(somecomplicatedconditionisnotfalseinverted()) // <-- this is already complicated enough, let's not ! that.
; // do nothing
else {
ohnoes();
}
But in your example, it does absolutely nothing when built for release and just adds a nop when built for debug, so you can drop a breakpoint on it.

When are curley braces required around single statements?

In my answer here: C# Lock syntax - 2 questions, LukeH pointed out that try...catch...(finally) statements require curly braces.
I found the answers as to why, found here ( Why do try..catch blocks require braces? ) very interesting.
I'd like to know of any more examples where curly braces are required as opposed to good practice etc, ideally with code snippet and explanation as to why.
Around a method body.
// not allowed:
int Inc(int x)
return x+1;
The why is not so easy, it would seem old-style C needed it more than C++/C#.
A little more about the why part, in (very) old C you would write
int Sum()
int a, b; // parameters, very informal
{
int s; // local var
...
}
So this ancient syntax needed the braces. And in all the languages that are based on C, nobody ever saw a point in making them optional, assuming that was possible in some cases.
Certain parts of language require braces to be present. For example, when you start a method you have to open and close braces to identify that as a code block. Inside a function certain language features like loops, conditinal statements, etc. also accept braces although in some cases they are not required. For example:
if (someValue == true)
doSomething();
In this case braces are not required, however you can surround this statement with braces, because you have just one statement that will be executed after if check, but if you want to execute multiple statement inside an if you need to use braces. For example,
if (someValue == true)
{
doSomething();
doSomeMoreWork();
}
Trying something like this is not allowed:
if (someValue == true)
doSomething();
doSomeMore();
else
doWork2();
int i = 1 + 2;
Compiler will complain in this case.
The problem can best be seen in the following loop:
while(i < 10)
doSomeWork();
i++;
Here you would expect i to increment, but this never happens. Basically this loop is the same as this one:
while(i < 10)
{
doSomeWork();
}
i++;
The statement inside the block will execute infinetly and i will never increment. In that case the proper way to write this statement would be:
while(i < 10)
{
doSomeWork();
i++;
}
Now you have a properly working statement. I like to use braces all the time regardless of number of statements that are being executed. The reason for this is that sooner or later I might need to add some more work in my if statement or inside a for or foreach loops. It's just a good practice.
You must use either braces or parentheses with checked and unchecked, depending on whether you're treating them as operators or statements:
// legal operator
int y = checked(x * 2);
// legal statement
unchecked
{
if ((a * b) > c)
{
DoSomething();
}
}
// illegal operator
int y = checked x * 2;
// illegal statement
unchecked
if ((a * b) > c)
DoSomething();
class/struct/interface declaration
class X { int _myval }

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