Author Topic: Comments...  (Read 5960 times)

0 Members and 1 Guest are viewing this topic.

Glenn R

  • Guest
Comments...
« on: February 22, 2007, 06:56:04 PM »
Found this in a book  :-o

Code: [Select]
try
{
    TextReader tr = new StreamReader(locationTextBox.Text);
    try
    { displayTextBox.Text = tr.ReadToEnd(); }
    catch (Exception ex)
    { MessageBox.Show(ex.Message); }
    finally
    { tr.Close(); }
}
catch (System.IO.FileNotFoundException ex)
{ MessageBox.Show("Sorry, the file does not exist."); }
catch (System.UnauthorizedAccessException ex)
{ MessageBox.Show("Sorry, you lack sufficient privileges."); }
catch (Exception ex)
{ MessageBox.Show(ex.Message); }

Let the discussion begin...

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Comments...
« Reply #1 on: February 22, 2007, 07:19:55 PM »
When your thingie is on the block, thats the way I'd probably do it .. the options are limited I think.

Part of the problen with just hacking to get stuff to work is that I forget that it should work "nicely".

I'd be interested in seeing a more elegant way to do that.

Perhaps something like ..
Code: [Select]
        try
        {
            using (TextReader tr = new StreamReader("TestFileStuff.txt"))
            {

« Last Edit: February 22, 2007, 07:21:09 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: Comments...
« Reply #2 on: February 22, 2007, 07:30:21 PM »
I agree that it should easy to read, as Bobby would say.
Agreed - you could use a using statement and most of the time I would.

I am, of course, referring to how ugly it is.

The author at this point in the book, exception handling, was talking about try/catch/finally and how variables declared inside the try block are not visible to the catch block...simple stuff. He then proceeds to wrap yet another expensive catch block around the first, nesting them and making it more difficult to decipher.

I would write it like so:
Code: [Select]
TextReader tr = null;
try
{
tr = new StreamReader(locationTextBox.Text);
displayTextBox.Text = tr.ReadToEnd();
}
catch (System.IO.FileNotFoundException ex)
{
MessageBox.Show("Specified file does not exist.");
}
catch (System.UnauthorizedAccessException ex)
{
MessageBox.Show("Insufficient privileges.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (tr != null)
tr.Close();
}

Far more readable in my opinion.
« Last Edit: February 23, 2007, 09:02:52 PM by Glenn R »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Comments...
« Reply #3 on: February 22, 2007, 08:01:52 PM »
By any chance was it
"Microsoft .NET Framework 2.0 - Application Development Foundation"

?
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: Comments...
« Reply #4 on: February 22, 2007, 08:11:09 PM »
< narrows eyes > Maybe... :-D
That's very intuitive Kerry...what made you think of it?

Or you could do it as you suggested Kerry:
Code: [Select]
try
{
using (TextReader tr = new StreamReader(locationTextBox.Text))
displayTextBox.Text = tr.ReadToEnd();
}
catch (System.IO.FileNotFoundException ex)
{
MessageBox.Show("Specified file does not exist.");
}
catch (System.UnauthorizedAccessException ex)
{
MessageBox.Show("Insufficient privileges.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

The using block calls dispose on the streamreader, regardless and dispose calls close().
I would use either approach...depends on what I'm doing at the time.
« Last Edit: February 22, 2007, 08:56:44 PM by Glenn R »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Comments...
« Reply #5 on: February 22, 2007, 08:32:21 PM »
< narrows eyes > Maybe... :-D
That's very intuitive Kerry...what made you think of it?


'cause as well as being handsome and witty and intelligent I've been known to mind-read on occasion.

If I could just master grammar I'd be really happy. :lol:
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Comments...
« Reply #6 on: February 22, 2007, 08:46:16 PM »
you may have an extra constructor invoked for tr .. yes ?
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: Comments...
« Reply #7 on: February 22, 2007, 08:59:06 PM »
What extra constructor? 8-)

Damn! I was cutting and pasting in VS for formating < sheepish grin >
Good spot.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Comments...
« Reply #8 on: February 23, 2007, 10:27:50 AM »
I know nobody really has time for writing tutorials, but I wish we had more on the subject of .Net and Autocad.  Part of my frustration is the lack of examples that show/tell WHY things are the way they are or how something should be done.  I myself do not learn by example very well.  I know there are examples that have been posted, but even those are not bullet proof.  Kerry helped me rewrite the examples from Autodesk, b/c they really didn't work as presented.

An example of what I'm referring to, would be the above post.  Just looking at the try/catch block, followed by more catch blocks, went right over my head.  I thought the try catch finally block was "one" block of code.  So what are all the catch blocks below that.  Is that good coding practice or was it thrown together, and it happened to work.  Does any of this make sense?

I guess I'm waiting on a book similiar to the VBA books for Autocad that explain in the most basic of terms how a method works, and give a really small example.  That will probably never be published, so I will have to bang my head against the wall til it works.  Thank goodness for you guys here at the Swamp!
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Comments...
« Reply #9 on: February 23, 2007, 11:28:50 AM »
Okay I will try and explain the example of the try/catch/finally as I understand it.

First you open with 'try', this is telling the program to try and do all the things in this area.  Here it is trying to create a new 'SteamReader' process (object), and then use it to read the whole file and show a dialog box of all the content.

Then the 'catch' will catch all errors that are thrown.  I have read that it is good practice to code it like this so that you can show more precise what has happened wrong.  It's kind of like a 'cond' statement in Lisp, and a 'case' (I think this is correct) in VBA.  It will step through each 'catch' and fire the first one that it matches.

The last part is the 'finally' part.  Here is where you do what you have to do to close objects that might be opened in the 'try' part.  Anything that NEEDS to be done, goes in this part.  This part is called no matter what.  The 'catch' part is only called when an error happens, but the 'finally' part is called weither an error happens or not.

Hope that makes some sense, as that is how I understand it.  :-)
If any statements are wrong, please let me know.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Chuck Gabriel

  • Guest
Re: Comments...
« Reply #10 on: February 23, 2007, 11:50:25 AM »
I think Glenn's main point was just that the nested try/catch is ugly, redundant, and confusing, and perhaps that it is a little disheartening to see code of that caliber presented as an "example" for others to follow.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Comments...
« Reply #11 on: February 23, 2007, 12:29:12 PM »
I agree.  T.W., your explanation makes sense, and that is how I understand the T/C/F statement as well.  As Chuck said, the example is ugly, and not a good "example" of how to code the statements.
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Comments...
« Reply #12 on: February 23, 2007, 12:52:12 PM »
I agree.  T.W., your explanation makes sense, and that is how I understand the T/C/F statement as well.  As Chuck said, the example is ugly, and not a good "example" of how to code the statements.
Agreed.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: Comments...
« Reply #13 on: February 23, 2007, 02:08:03 PM »
Found this in a book  :-o

I hate reading through a book and seeing bad example code.  It taints the experience, even if the overall content is good.  There have been times when I would put a book down when I ran into examples like this.  Now I try to focus on the fact that I probably learn more from seeing the bad than the good.

Now pardon me while I scurry off to see how poorly written the example code in my last few handouts has been :-)

Bobby C. Jones

Glenn R

  • Guest
Re: Comments...
« Reply #14 on: February 23, 2007, 09:00:55 PM »
I think Glenn's main point was just that the nested try/catch is ugly, redundant, and confusing, and perhaps that it is a little disheartening to see code of that caliber presented as an "example" for others to follow.

Spot on Chuck. I'm begining to think the doctors are right ;)

Glenn R

  • Guest
Re: Comments...
« Reply #15 on: February 23, 2007, 09:17:52 PM »
Let me expand a little on Tim's explanation.

First off, in C++ and to SOME extent in C#, curly braces {} define a CODE BLOCK, or, more importantly, a SCOPE. In C++/ARX, I would declare a smart pointer (you listening Chuck) deliberately INSIDE a set of curly braces. Why? The reason is simple. Automatic variables on the stack are destroyed immediately upon exit from a CODE BLOCK. Hence, the destructor is immediately called for the smart pointer and it's closed and destroyed - nice and neat.

The closest we have to that in C# is the 'Using' statement. Now, it doesn't necessarily have to have curly braces as it could be one line, as my example above. The important part about it is simialr to the C++ description - upon exiting the using 'block', the variables you are using immediately have their 'Dispose()' method called, essentially cleaning up the resources the object used. Incidentally, a 'using' statement produces IL that is if you had written a try/finally construct.

A try/catch/finally construct IS one block, if you will. You can't have a try without either a catch AND/OR finally clause. Now, the order of the catch clauses is VERY VERY important. As Tim pointed out, the runtime will evaluate each catch clause and immediately execute the one that matches. However, you have to remember one thing - ALL exception classes ultimately inherit from System.Exception. So, as all other exceptions DERIVE/INHERIT from System.Exception, the catch clauses MUST go from MOST SPECIFIC to LEAST SPECIFIC.

An example. Imagine if your code threw an FileNotFoundException and you catch blocks went in this order: System.Exception THEN FileNotFoundException. The FileNotFoundException catch clause would NEVER execute seeing as it derives from System.Exception and it was the first one tried. Inheritance/polymorpphism rules come into play.

The golden rule for catch clauses: MOST to LEAST specific.

Cheers,
Glenn.
« Last Edit: February 23, 2007, 09:22:21 PM by Glenn R »