[Proposal] using statement enhancements

  • Thread starter Thread starter cody
  • Start date Start date
C

cody

Mostly always you use the using clause you deal with native ressources, so
exception handlinjg is sooner or later inevitable.

so why do we need to write

try
{
using (File f = File.CreateText("bla.txt"))
{
}
}catch (IOExcepion e)
{
}

why don't we allow catch blocks directly attached to the using clause:

using (File f = File.CreateText("bla.txt"))
{
}
catch (IOExcepion e)
{
}

It is much shorter and readable. One of the problems with Exceptions is that
is often produces very deep nested code and at the end you do not know which
belongs to what.

The second idea I have is that we need some support for transactions in
code. Currently we have to write huge statements like that to enable safe
transaction handling:

try
{
BeginTransaction();
// stuff
Commit();
}
catch (SpecialException e)
{
Rollback();
throw new SpecialException ("Something fouled up here", e);
}
catch (Exception)
{
Rollback();
throw;
}

So I'd love to see that in future using would accept next to IDisposible a
new interface ITransaction:

interface ITransaction
{
void BeginTransaction();
void Commit();
void Rollback();
}

so we could write code like that:

using (dbconnection.Transaction)
{
// do stuff here
}

the property Transaction would return an (not necessarily a new) object
implementing ITransaction and BeginTransaction, Commit and Rollback are
automatically called. If the object additionally implements IDisposible
dispose is also called in the finally clause.

What do you think?
 
The second idea I have is that we need some support for transactions in
code. Currently we have to write huge statements like that to enable safe
transaction handling:

The usual idiom is something like:

Transaction t = Transcations.Begin(...);
bool committed = false;
try {
while ( still_not_done() )
t.Operate(...);
committed = t.Commit();
} finally {
if ( !committed )
t.Rollback();
}

Which nicely lets exception go to the caller of something goes wrong,
and completes cleanly otherwise.
 
Helge Jensen said:
The usual idiom is something like:

Transaction t = Transcations.Begin(...);
bool committed = false;
try {
while ( still_not_done() )
t.Operate(...);
committed = t.Commit();
} finally {
if ( !committed )
t.Rollback();
}

Which nicely lets exception go to the caller of something goes wrong,
and completes cleanly otherwise.

Actually, the using statement covers this already:

using (Transaction t = Transactions.Begin(...))
{
.. do stuff ..
t.Commit();
}

Every transaction class I've seen implements IDisposable in a way such
that if it's disposed without committing, the transaction is rolled
back, and if it's disposed after committing that's a no-op.
 
cody said:
Mostly always you use the using clause you deal with native ressources, so
exception handlinjg is sooner or later inevitable.

Well, I don't agree that exception handling is in any way inevitable
*in the same scope as the using statement*, but I agree it happens.
so why do we need to write

try
{
using (File f = File.CreateText("bla.txt"))
{
}
}catch (IOExcepion e)
{
}

why don't we allow catch blocks directly attached to the using clause:

using (File f = File.CreateText("bla.txt"))
{
}
catch (IOExcepion e)
{
}

Yup, that would be nice for the cases where you *do* need to handle
exceptions at the same level.
 
For your first suggestion:
why don't we allow catch blocks directly attached to the using clause:

using (File f = File.CreateText("bla.txt"))
{
}
catch (IOExcepion e)
{
}

You have a problem when it comes to providing a useful error message in the
event of a syntax error. This is an important issue with the IDE as well.
For example, let's assume this syntax exists. Also, let's assume that
try-catch also continues to exist. The following errant code is entered in
the IDE. Where should the error be flagged? (At point one or point two?)

public void mycall()
{
try
{ // do some stuff
//point one
using (File f = File.CreateText("bla.txt"))
{
} // point two
catch (IOExcepion e)
{
}
} // point three

I didn't put in indentation on purpose... the compiler ignores indentation.

OK... so where's the bug? If an close brace is added at point one, then the
catch goes with the using. If the close brace is added at point two, then
the catch goes with the try. Assume there is a LOT of code in here. The
IDE could easily instruct the developer to add a brace at the wrong place.
In fact, it would be difficult to catch the error before point three (end of
the method)!

This is one reason why block groups (like "catch" and "else") are not reused
in multiple structures.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
You have a problem when it comes to providing a useful error message in
the event of a syntax error.

You must be joking if that is the only problem you have with that :)
In my experience, a missing } often lets the compiler point to the end of
the file or the beginning of the next class, even if the brace is missing
somewhere in the middle of the class. I have no problem with that because it
happens very rarely and usually its no problem to spot the error.
 
I'm really glad that you are not designing a language that I would have to
actually use, Cody.

I've been writing code professionally since the early 80's. The list of
languages is long, and the list of tools to write them in is longer.

I can tell you one thing: making a language less usable because you think
your structure is cool... will get you a dead language.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
Back
Top