views:

959

answers:

15

The commonly accepted way to format C# code seems to be as follows:

namespace SomeNamespace
{
    namespace SomeSubNamespace
    {
        class SomeClass
        {
            void SomeFunction()
            {
                using (var someFile = new StreamWriter(somePath))
                {
                    try
                    {
                        lock(someCriticalSection)
                        {
                            using (var someDisposableThing1 = new DisposableThing())
                            {
                                DoSomething();                            
                                using (var someDisposableThing2 = new DisposableThing())
                                {
                                    lock(someOtherCriticalSection)
                                    {
                                        DoSomethingMore();
                                    }
                                }
                            }
                        }
                    }
                    catch(Exception e)
                    {
                        Log(e);
                    }
            }
        }
    }
}

This wastes a large amount of screen space, both horizontally and vertically. I'm surely not the first person who notices. My question is: do you live with it, or have you developed a different formatting style to avoid an excess of white space?

PS: Note that I didn't even use a single if statement yet!

+7  A: 

I tend to write small classes, short methods with small level of nesting. Not only you can see everything on your screen, also the code is better!

Grzenio
+5  A: 

I have a 24" widescreen monitor. I greatly prefer "pretty-printing" over reclaiming space. Condensed, crammed-together code is hard to read and hurts my brain.

Dave Swersky
+1 Hard to maintain, hard for peers to pick it up after you're done. It's icky.
Jimmy Hoffa
+19  A: 
  1. I don't often see namespaces nested in that way - maybe it happens, not where I work
  2. I live with it. And mostly don't write such deeply-nested code. Having shorter methods, or methods with less nesting certainly reduces the horizontal whitespace problem, and having methods broken up into smaller pieces means you can get more important information in a given amount of vertical space.
Blair Conrad
Agreed. I don't think I've ever seen namespaces nested like that either.
Ryan Bennett
I've never seen someone nest namespaces like that, the only reason to do it instead of namespace SomeNamespace.SomeSubNamespace would be to add a class into each of the namespaces, in which case you've got two classes in one file which is a no-no, especially if both classes are in different namespaces - their files should be in different folders then.
Jimmy Hoffa
Unfortunately I have seen namespaces like that.
rick schott
+1 one writing smaller methods.
Steven
We don't have to live with it! We're the programmers, it's in our power to change the code. Each method should do 1 thing and do it well.
George Stocker
@Jimmy Hoffa, maybe they came from managed C++, where I think you have to nest the namespaces that way. At least, you did in .NET 1.1Land.
Blair Conrad
+10  A: 

Well I bought an HD monitor ;)

But the only way to deal with it apart from using less indenting would be to move some code into their own methods.

chris166
+3  A: 

If I'm going to try/catch something, I would combine with any adjacent using blocks. Similarly, I would aggregate namespaces, so something closer to:

namespace SomeNamespace.SomeSubNamespace
{
    class SomeClass
    {
        void SomeFunction()
        {
            StreamWriter someFile;
            try
            {
                someFile = new StreamWriter(somePath);

                lock(someCriticalSection)
                {
                    using (var someDisposableThing1 = new DisposableThing())
                    {
                        DoSomething();                            
                        using (var someDisposableThing2 = new DisposableThing())
                        {
                            lock(someOtherCriticalSection)
                            {
                                DoSomethingMore();
                            }
                        }
                    }
                }
            }
            catch(Exception e)
            {
                Log(e);
            }
            finally
            {
                if( someFile != null )
                {
                     someFile.Dispose();
                }
            }
        }
    }
}
Rowland Shaw
+3  A: 

Don't think it looks so bad either ;) Making shorter functions however really is a point. In particular, it's nice if you can do stuff like replacing

if (condition)
{
   // bla
}
else
{
  // blub
}

by

void someFunction()
{
  if (condition)
  {
    // bla
    return
  }
  // blub
}
Nicolas78
Absolutely!!! I hate seeing nested `if`s everywhere.
Dave
Not sure that makes much difference, and I'd argue it reduces readability if `// bla` is of any significant length. I won't -1 though, 'cause I admit it's pretty subjective...
Dan Puzey
Dan: For me it's more important whether //blub is of significant length because then you benefit from a lot of //blub being indented one level lower (edit, misread your point at first, I kinda agree but I'd still weigh it to the benefit of //blub. I think it makes most sense if //bla is error handling and there may even be //bla1 // bla2 etc clauses)
Nicolas78
+16  A: 

Let me explain it like this. If you really happen to encounter a nested code construct as deep as the one you show above, then the problem is probably not the formatting but your code structure.

You should consider taking a look at this: Refactoring by Martin Fowler

By extracting methods you improve not only the "wasted" screen space, but you dramatically increase readability too ;)

Another solution is always: Alt + Shift + Enter in Visual Studio to go into Full Screen mode

Juri
ALT + *SHIFT* + ENTER to fullscreen VS
matthew.perron
@matthew: thx :) forgot the shift, but corrected it now
Juri
Alt + Shift + Enter in VS; Ctrl + M in Eclipse
Vash
+2  A: 

I agree with the other answers that I basically live with it -- for my team we either have high-res monitors or dual monitors (or both), so it's not like we're developing on 800x600.

But one thing to keep in mind is that your tabbing would be better off if you used actual spacing, as some developers use 2 spaces for a tab, some 4, some 6. So while formatted code may look fine on one developer's IDE, it may not look so good on another's. (I've seen some horrible outcomes from that.)

VS2010 has a nice plug-in from the Extensions Manager called the Productivity Tools that detects when you have a mix of tabs and spaces in your file and allows you to convert everything to tabs or spaces ("Fix Mixed Tabs"). It really helps to clean up your file (even if it doesn't look like it does anything!). It's great if you're sharing code across teams.

David Hoerster
Why the downvote? No comment -- kind of rude.
David Hoerster
+10  A: 

Tools > Options > Text Editor > All Languages > Tabs > Indent size > 1
Not a great solution... :P

SwDevMan81
A guy I work with change his tabs to 2 ... works for him
Martin
actualy, 2-space tabs are a great solution. +1
tenfour
+1 this is why **everyone** should **always** indent using tabs and not spaces (gotta love these everlasting flame wars!)
Martin
@Martin - Yeah, I usually select the 'Insert Spaces' radio button (and set the 'Tab size' and 'Indent Size' to the same value). I do hate those Tabs! :)
SwDevMan81
Personally, I find any indent less than 4 spaces is too small to easily see indenting levels. (Just yesterday was looking at an XML file with 2-space tabs - yuck!). Make sure everyone on your team is OK with that, or everyone indents with tabs, like Martin suggests.
Tom Bushell
+1  A: 

use CodeRush , it'll make navigation through out your code much better

you'll get something like this alt text

George
+4  A: 

I've seen open brackets on the beginning line of a code block as in:

namespace SomeNamespace { 
    class SomeClass {
        void SomeFunction() {
            using (var someFile = new StreamWriter(somePath)) {
                try {
                    lock(someCriticalSection) {
                        using (var someDisposableThing1 = new DisposableThing()) {
                            DoSomething();                             
                        }
                    }
                } catch(Exception e) { 
                    Log(e); 
                } 
            }
        } 
    } 
} 

Less real estate, but I think its ugly.

Ryan Bennett
Ugly indeed. blech.
Jimmy Hoffa
Yeah a consultant at my last place swore up and down by this formatting. I wanted to throw up everytime I looked at his stuff.
Ryan Bennett
Beauty is in the eyes of the beholder. But this is some fugly stuff indeed.
matthew.perron
I think it's ugly because it's very inconsistent. `using (` yet `lock(`; `) {` yet `)\n{`. Two of the `}`'s don't line up, either. And of course the number of spaces per indention level isn't consistent.
strager
I'm using this style and like it. But you're not using it where it has the biggest advantage saving screen space: put "`} catch (Exception e) {`" onto a single line. And you've misplaced the `{` for the namespace statement as well - if you demonstrate this style, please do so consistently.The `}` lines up nicely with the keyword opening the block (instead of lining up with the `{`).
Daniel
Sorry for the inconsistancy - I don't use it. I've just seen it.
Ryan Bennett
I prefer this style - saves vertical spaces for things that are actually important (like new lines between blocks of code) instead of wasting them on redundant braces (indentation already shows you scoping level).
Mark Brackett
This style is far nicer. I don't know why some people don't like it!
BG100
This is the default style in the java world, and I like it. I can't stand all those wasted lines with the braces all by themselves.
Peter Recore
I am a huge fan of this style. I used to be religiously opposed to it, and then I started writing Python code. When I came back to C#, it just didn't feel natural anymore to put braces on their own lines. In fact, the very idea of braces kind of seemed... obsolete.
Nick Aceves
+9  A: 

You should read Bob Martin's Clean Code. It helps with this problem. In this instance, SomeFunction() does more than one thing. Split out each thing it does in its own method.

 namespace SomeNamespace.SomeSubNamespace
 {
    class SomeClass
    {
        void WriteToFile()
        {
            using (var someFile = new StreamWriter(somePath))
            {
                lock(someCriticalSection)
                {
                   ExecuteCriticalSection();
                }
            }
        }
        void ExecuteCriticalSection()
        {
            using (var someDisposableThing1 = new DisposableThing())
            {
            DoSomething();
            ExecuteFinalCriticalSection();
            }   
        }

        void ExecuteFinalCriticalSection()
        {
            using (var someDisposableThing2 = new DisposableThing())
            {
            lock(someOtherCriticalSection)
                {
                DoSomethingMore();
                }
            }
        }
    }
}

Also, don't catch a System.Exception; you never know what's going to fail, and you shouldn't try to catch exceptions you can't handle. Let them bubble up and die horribly.

George Stocker
+1 for the System.Exception, I have to debate that all the time.
rick schott
What's better in an enterprise application? Capturing System.Exception, logging it and saving or sending to support or having user to deal with .NET exception message they do not even bother to read and application crash?
Grozz
@Grozz If you capture a system exception and log it, you could have corrupted state in your log; not to mention then it's incumbent upon the developers to check the log. With a horrible exception popping up and making your users mad, it's easier to find problems in the application that you didn't find in development.
George Stocker
+1! I'd say logging is OK, but if you do, RETHROW!! Your application is now in an unknown state.
TrueWill
Lately I've been practicing a discipline that I call "Extract till you drop". I will extract functions until I cannot extract anymore. This is a good way to guarantee that your functions do only one thing. So in the above, I would extract out the lock clauses into their own functions.
Robert C. Martin
@Robert C. Martin Thanks! I don't do much `lock` ing so I didn't know if that was possible, but I'll redo the code to see the effect.
George Stocker
+1  A: 

In addition to what others have said here, the one thing I do to lessen the effect, is to use a proportional-spaced font. The text is more readable, but not nearly as wide. It also forces you to use tabs over spaces for alignment (which is of course, why the good Lord gave us tabs in the first place)

I personally use Comics Sans MS, but that really drives coworkers crazy....

James Curran
We have horizontal space in abundance, it's the vertical space that is premium. Using a proportional-spaced font makes code look odd and hard to read. Maybe that's because I've been coding since long before there were proportional-spaced fonts (before video modes other than text mode were available).
Tergiver
haha comic sans. Actually I have tried proportional fonts and they are not as annoying as I expected. But it's something to get used to, and currently there are too many things in my work which rely on mono-spaced alignment to look pretty. I don't have any issues with code being too wide though.
tenfour
The OP specifically mentioned horizontal and well and verticle space. And @Tergiver, I've got 6 years on you on those monitors.
James Curran
@Tergiver - I find long lines within a method (using too much horizontal space) just as bad. Shows how subjective a lot of this is.
Tom Bushell
+3  A: 

The using statement is very handy, but if code becomes harder to read you can do without it:

namespace SomeNamespace.SomeSubNamespace
{
    class SomeClass
    {
        void SomeFunction()
        {
            StreamWriter someFile = new StreamWriter(somePath);
            DisposableThing someDisposableThing1 = null;
            DisposableThing someDisposableThing2 = null;

            try
            {
                lock (someCriticalSection)
                {
                    someDisposableThing1 = new DisposableThing();
                    DoSomething();
                    someDisposableThing2 = new DisposableThing();
                    lock (someOtherCriticalSection)
                    {
                        DoSomethingMore();
                    }
                }
            }
            catch (Exception e)
            {
                Log(e);
            }
            finally
            {
                // requires SafeDispose extension method
                someFile.SafeDispose();
                someDisposableThing1.SafeDispose();
                someDisposableThing2.SafeDispose();
            }
        }
    }
}
Tergiver
+1  A: 

Some general ideas:

  • Combine those namespace blocks into one.
  • Gather using statements into one place, if you can.
  • If you're not a fanatic "Even single statements need enclosing {}s!", you could get rid of the brackets between the using and the try..catch blocks.
  • Think about whether nested locks are really required, or if the outermost lock will suffice.

These could result in the following code (take note that the meaning of your hypothetical example code may not be exactly preserved):

namespace SomeNamespace.SomeSubNamespace
{
    class SomeClass
    {
        void SomeFunction()
        {
            using (var someFile = new StreamWriter(somePath))
            try
            {
                lock(someCriticalSection)
                {
                    using (var someDisposableThing1 = new DisposableThing())
                    using (var someDisposableThing2 = new DisposableThing())
                    {
                        DoSomething();                            
                        DoSomethingMore();
                    }
                }
            }
            catch(Exception e)
            {
                Log(e);
            }
        }
    }
}

(You could even move the two usings to the other using statement outside of the lock, if your code would permit it. You could further replace using statements with explicit calls to Dispose in a finally block, as suggested in another answer.)

stakx
Thanks for your interesting response. A small remark though: the scope of locks generally has to be made as small as possible because of performance and to avoid deadlocks. Therefore it seems unlikely that it is possible to combine multiple mutexes.
Dimitri C.
_@Dimitri:_ Perhaps I don't understand `lock` as well as I should: I can see the point of keeping locks as short as possible; however, I don't see why you'd *need* the inner lock, since the outer lock already makes sure that the code is only executed by one thread at a time... What's more, the outer lock's duration is *not* increased by removing the inner lock. -- What am I getting wrong here?
stakx