I am using Visual Studio 2K3 writing a ASP.NET web application. Is there a way to force the C# compiler to catch possible exception? In Java, all exceptions thrown MUST BE caught, otherwise compiler would give you error. In C#, is there a way to do that?
Nope C# doesn't support checked exceptions. Heres a transcript of Bruce Eckle and Anders Hejlsberg discussing why they are not in C#. http://www.artima.com/intv/handcuffs.html Regards Richard Blewett - DevelopMentor http://www.dotnetconsult.co.uk/weblog http://www.dotnetconsult.co.uk I am using Visual Studio 2K3 writing a ASP.NET web application. Is there a way to force the C# compiler to catch possible exception? In Java, all exceptions thrown MUST BE caught, otherwise compiler would give you error. In C#, is there a way to do that?
now you know why I don't use Java. No, C# will not FORCE you to catch your errors. That's up to you to do, and it makes sense. You don't always want to catch every error locally. While it is good practice, it should not be an absolute requirement. --- Nick [quoted text, click to view] "ChInKPoInt [No MCSD]" <ChInKPoIntNOSPAMURASS@gmail.com> wrote in message news:G5ydnVLSx4R58CfcRVn-hw@rogers.com... > I am using Visual Studio 2K3 writing a ASP.NET web application. Is there a > way to force the C# compiler to catch possible exception? > > In Java, all exceptions thrown MUST BE caught, otherwise compiler would give > you error. In C#, is there a way to do that? > > >
"Richard Blewett [DevelopMentor]" <richardb@NOSPAMdevelop.com> wrote in message news:uGslds33EHA.3368@TK2MSFTNGP10.phx.gbl... [quoted text, click to view] > Nope C# doesn't support checked exceptions. Heres a transcript of Bruce > Eckle and Anders Hejlsberg discussing why they are not in C#. > > http://www.artima.com/intv/handcuffs.html I find the "versioning" argument here weak, for two reasons: The implication is that a method void M() throws A, B, C throws precisely A, B and C, and that this handcuffs you in reimplementing the method. In fact, the method can be changed to throw any subclass of A, B or C without breaking compatibility. If you're designing a method that has to remain compatible (one in a widely used library, like the .NET Framework) A, B and C should be categories of exception like IOException, not the specific IO exceptions that can be thrown in the first implementation. One advantage of checked exceptions is that it allows the documentation to know which exceptions are thrown. Compare the JDK Javadoc with the .NET API documentation. You'll see how much better the Javadoc is about showing which exceptions are thrown and why.
[quoted text, click to view] Nick Malik <nickmalik@hotmail.nospam.com> wrote: > now you know why I don't use Java. > > No, C# will not FORCE you to catch your errors. That's up to you to do, and > it makes sense. You don't always want to catch every error locally. While > it is good practice, it should not be an absolute requirement.
It's not in Java. You don't have to catch every exception (or even checked exception) locally - you just have to declare which checked exceptions you can throw. I believe that checked exceptions of some kind are a good idea; I'm not sure that Java got it right, and C#/.NET didn't get it right by getting rid of them entirely. Java feels slightly cumbersome because of them, and C# sometimes feels like driving without a seatbelt due to the lack of them. The first language/platform which gets exception handling really "right" will be interesting... -- Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet
[quoted text, click to view] "Mike Schilling" <mscottschilling@hotmail.com> wrote in message news:eZ5px853EHA.3236@TK2MSFTNGP15.phx.gbl... > > "Richard Blewett [DevelopMentor]" <richardb@NOSPAMdevelop.com> wrote in > message news:uGslds33EHA.3368@TK2MSFTNGP10.phx.gbl... >> Nope C# doesn't support checked exceptions. Heres a transcript of Bruce >> Eckle and Anders Hejlsberg discussing why they are not in C#. >> >> http://www.artima.com/intv/handcuffs.html > > I find the "versioning" argument here weak, for two reasons: > > The implication is that a method > > void M() throws A, B, C > > throws precisely A, B and C, and that this handcuffs you in reimplementing > the method. In fact, the method can be changed to throw any subclass of > A, B or C without breaking compatibility. If you're designing a method > that has to remain compatible (one in a widely used library, like the .NET > Framework) A, B and C should be categories of exception like IOException, > not the specific IO exceptions that can be thrown in the first > implementation. How much does it really help you to know that the method throws some kind of IOException without telling you which ones? Also, for versioning, consider the case where a method had previously been written to handle FileStream I/O and therefore had a throws IOException but now wants to be able to get data from a network as well. The FileStream parameter is changed to Stream, and the throws clause is changed to include NetworkException, and you've got a versioning problem. [quoted text, click to view] > One advantage of checked exceptions is that it allows the documentation to > know which exceptions are thrown. Compare the JDK Javadoc with the .NET > API documentation. You'll see how much better the Javadoc is about > showing which exceptions are thrown and why.
Should ease of automatic documentation be a reason to implement a language feature like this? An <exception> tag in Xml comments in C# solves this problem without constraining the language. John Saunders
[quoted text, click to view] > I believe that checked exceptions of some kind are a good idea; I'm not > sure that Java got it right, and C#/.NET didn't get it right by getting > rid of them entirely. Java feels slightly cumbersome because of them, > and C# sometimes feels like driving without a seatbelt due to the lack > of them. The first language/platform which gets exception handling > really "right" will be interesting...
Yet...somehow I think you'll still find a large percentage of people who like the java or C# way... I wonder what right is.
[quoted text, click to view] "John Saunders" <johnwsaundersiii at hotmail.com> wrote in message news:uYxvLW73EHA.4092@TK2MSFTNGP14.phx.gbl... > "Mike Schilling" <mscottschilling@hotmail.com> wrote in message > news:eZ5px853EHA.3236@TK2MSFTNGP15.phx.gbl... >> >> "Richard Blewett [DevelopMentor]" <richardb@NOSPAMdevelop.com> wrote in >> message news:uGslds33EHA.3368@TK2MSFTNGP10.phx.gbl... >>> Nope C# doesn't support checked exceptions. Heres a transcript of Bruce >>> Eckle and Anders Hejlsberg discussing why they are not in C#. >>> >>> http://www.artima.com/intv/handcuffs.html >> >> I find the "versioning" argument here weak, for two reasons: >> >> The implication is that a method >> >> void M() throws A, B, C >> >> throws precisely A, B and C, and that this handcuffs you in >> reimplementing the method. In fact, the method can be changed to throw >> any subclass of A, B or C without breaking compatibility. If you're >> designing a method that has to remain compatible (one in a widely used >> library, like the .NET Framework) A, B and C should be categories of >> exception like IOException, not the specific IO exceptions that can be >> thrown in the first implementation. > > How much does it really help you to know that the method throws some kind > of IOException without telling you which ones? Quite a bit. public void close() throw IOException; Java reminds you that a close does I/O that can fail (in particular buffer flushing.) C# doesn't. Any guesses how much C# code handles failures in Close() ? [quoted text, click to view] > > Also, for versioning, consider the case where a method had previously been > written to handle FileStream I/O and therefore had a throws IOException > but now wants to be able to get data from a network as well. The > FileStream parameter is changed to Stream, and the throws clause is > changed to include NetworkException, and you've got a versioning problem.
Not when Network exception is a subclass of IOException, which logically it will be. [quoted text, click to view] > >> One advantage of checked exceptions is that it allows the documentation >> to know which exceptions are thrown. Compare the JDK Javadoc with the >> .NET API documentation. You'll see how much better the Javadoc is about >> showing which exceptions are thrown and why. > > Should ease of automatic documentation be a reason to implement a language > feature like this? An <exception> tag in Xml comments in C# solves this > problem without constraining the language.
But the exception tags don't get put in C# methods, they do get put into the Java ones.
[quoted text, click to view] "Mike Schilling" <mscottschilling@hotmail.com> wrote in message news:eLNHSAA4EHA.1396@tk2msftngp13.phx.gbl... > > "John Saunders" <johnwsaundersiii at hotmail.com> wrote in message > news:uYxvLW73EHA.4092@TK2MSFTNGP14.phx.gbl... >> "Mike Schilling" <mscottschilling@hotmail.com> wrote in message >> news:eZ5px853EHA.3236@TK2MSFTNGP15.phx.gbl... >>> >>> "Richard Blewett [DevelopMentor]" <richardb@NOSPAMdevelop.com> wrote in >>> message news:uGslds33EHA.3368@TK2MSFTNGP10.phx.gbl... >>>> Nope C# doesn't support checked exceptions. Heres a transcript of Bruce >>>> Eckle and Anders Hejlsberg discussing why they are not in C#. >>>> >>>> http://www.artima.com/intv/handcuffs.html >>> >>> I find the "versioning" argument here weak, for two reasons: >>> >>> The implication is that a method >>> >>> void M() throws A, B, C >>> >>> throws precisely A, B and C, and that this handcuffs you in >>> reimplementing the method. In fact, the method can be changed to throw >>> any subclass of A, B or C without breaking compatibility. If you're >>> designing a method that has to remain compatible (one in a widely used >>> library, like the .NET Framework) A, B and C should be categories of >>> exception like IOException, not the specific IO exceptions that can be >>> thrown in the first implementation. >> >> How much does it really help you to know that the method throws some kind >> of IOException without telling you which ones? > > Quite a bit. > > public void close() throw IOException; > > Java reminds you that a close does I/O that can fail (in particular buffer > flushing.) C# doesn't. Any guesses how much C# code handles failures in > Close() ? All of mine does. ;-) Look, _anything_ can fail. It does you little good to know that Close() can throw IOException. How much does that help you over "throws Exception"? [quoted text, click to view] >> >> Also, for versioning, consider the case where a method had previously >> been written to handle FileStream I/O and therefore had a throws >> IOException but now wants to be able to get data from a network as well. >> The FileStream parameter is changed to Stream, and the throws clause is >> changed to include NetworkException, and you've got a versioning problem. > > Not when Network exception is a subclass of IOException, which logically > it will be.
Why? It isn't in .NET. Don't know about the Java case. If network exceptions are subclasses of IOException, then tell me what is _not_ a subclass of IOException (aside from Exception). [quoted text, click to view] >> >>> One advantage of checked exceptions is that it allows the documentation >>> to know which exceptions are thrown. Compare the JDK Javadoc with the >>> .NET API documentation. You'll see how much better the Javadoc is about >>> showing which exceptions are thrown and why. >> >> Should ease of automatic documentation be a reason to implement a >> language feature like this? An <exception> tag in Xml comments in C# >> solves this problem without constraining the language. > But the exception tags don't get put in C# methods, they do get put into > the Java ones.
The exception tags get put in by developers who want to document what exceptions are thrown, and it didn't take a language feature to get that done. And they're likely to be a lot more specific that "IOException". John Saunders
[quoted text, click to view] "John Saunders" <johnwsaundersiii at hotmail.com> wrote in message news:eE7lvKD4EHA.2192@TK2MSFTNGP14.phx.gbl... >> Java reminds you that a close does I/O that can fail (in particular >> buffer flushing.) C# doesn't. Any guesses how much C# code handles >> failures in Close() ? > > All of mine does. ;-)
Good for you. Mine too. A lot doesn't, just in as C, a lot didn't check the return status from close() or fclose(). [quoted text, click to view] > Why? It isn't in .NET. Don't know about the Java case. If network > exceptions are subclasses of IOException, then tell me what is _not_ a > subclass of IOException (aside from Exception).
Illegal argument? Invalid state? Concurrent modification? No such class/method/field? Access not allowed? etc. [quoted text, click to view] > >>> >>>> One advantage of checked exceptions is that it allows the documentation >>>> to know which exceptions are thrown. Compare the JDK Javadoc with the >>>> .NET API documentation. You'll see how much better the Javadoc is >>>> about showing which exceptions are thrown and why. >>> >>> Should ease of automatic documentation be a reason to implement a >>> language feature like this? An <exception> tag in Xml comments in C# >>> solves this problem without constraining the language. >> But the exception tags don't get put in C# methods, they do get put into >> the Java ones. > > The exception tags get put in by developers who want to document what > exceptions are thrown, and it didn't take a language feature to get that > done. And they're likely to be a lot more specific that "IOException".
Then why is the .NET framework documentation so poor in documenting exceptions compared to the JDK docs?
[quoted text, click to view] "Mike Schilling" <mscottschilling@hotmail.com> wrote in message news:uQgTYkH4EHA.2192@TK2MSFTNGP14.phx.gbl... > > "John Saunders" <johnwsaundersiii at hotmail.com> wrote in message > news:eE7lvKD4EHA.2192@TK2MSFTNGP14.phx.gbl... >>> Java reminds you that a close does I/O that can fail (in particular >>> buffer flushing.) C# doesn't. Any guesses how much C# code handles >>> failures in Close() ? >> >> All of mine does. ;-) > > Good for you. Mine too. A lot doesn't, just in as C, a lot didn't check > the return status from close() or fclose(). > >> Why? It isn't in .NET. Don't know about the Java case. If network >> exceptions are subclasses of IOException, then tell me what is _not_ a >> subclass of IOException (aside from Exception). > > > Illegal argument? > Invalid state? > Concurrent modification? > No such class/method/field? > Access not allowed? > etc. > > >> >>>> >>>>> One advantage of checked exceptions is that it allows the >>>>> documentation to know which exceptions are thrown. Compare the JDK >>>>> Javadoc with the .NET API documentation. You'll see how much better >>>>> the Javadoc is about showing which exceptions are thrown and why. >>>> >>>> Should ease of automatic documentation be a reason to implement a >>>> language feature like this? An <exception> tag in Xml comments in C# >>>> solves this problem without constraining the language. >>> But the exception tags don't get put in C# methods, they do get put into >>> the Java ones. >> >> The exception tags get put in by developers who want to document what >> exceptions are thrown, and it didn't take a language feature to get that >> done. And they're likely to be a lot more specific that "IOException". > > Then why is the .NET framework documentation so poor in documenting > exceptions compared to the JDK docs?
The JDK docs naturally document what's in the throws clauses. I'm not even sure whether the .NET documentation comes from Xml comments in C# code. John Saunders
[quoted text, click to view] "Helge Jensen" <helge.jensen@slog.dk> wrote in message news:41BCBD62.5010901@slog.dk... > Really, I wasn't going to comment on this holy-war, but I think I will > anyway.
Thanks for the comment, and thanks for bringing it out of .aspnet. I'll keep it in the list for a while, for anyone following this there, but if this goes on for long, I hope we can all agree that .aspnet time is over. :-) .... [quoted text, click to view] > *** NOTE: .NET Delegate's do exception wrapping, making catch on a > delegate-invocation a VERY delicate thing to try.
I was unaware of this. Could you provide some detail on this behavior? [quoted text, click to view] > PROPOSAL > -------- > > If it was possible to declare "throws" statements on functions and require > callers to either handle or declare the exceptions themselves (no > class-hierarchy spec. of what should be checked here), AND it was possible > to "uncheck" an exception, allowing the caller to knowingly pass a > previously checked exception from a function as unchecked, now that WOULD > be usefull. > > It would allow us to write the interface from above in the way we wanted, > without any throws qualifier, but it would allow File.Open to declare that > a FileNotFoundException could reasonably occur and that the caller should > do something about it.
I have some question in general about this entire area. The fact is that, when my code can handle an exception, I handle it. But when it doesn't have anything useful to contribute to the processing of the exception, I get out of the way and let my callers deal with it. Maybe the caller can handle the exception, even though there's nothing useful I can do with it right now. I _do_ sometimes wrap exceptions with something more application-specific. For instance, I have a Login method for logging in to a web service. This method will wrap a SoapException in a LoginFailedException. Presumably, my caller called me in order to log in, and should be told that the login failed. My Message says, "Can't log in as <username>", which is more useful than "required header not supplied in call". If my caller thinks he knows what to do about a SoapException, I supply it to him as the InnerException property, but I don't decline to give him useful information on the off chance that he really wanted to see that SoapException instead of my LoginFailedException. I assume that my callers are taking care of their IDisposable resources with "using" blocks or the equivalent. I assume they're backing out of anything else that needs backing out of with "finally" blocks. And I assume they have a strategy for what to do with exceptions that nobody has been able to handle. Maybe they've got a try-catch block around their message loop, or, perhaps they do like I often do in Windows Forms applications, and place their entire event handler in a try-catch block. Maybe my ultimate caller is an ASP.NET application which handles all unhandled exceptions in Global.asax and needs to e-mail exception details to the support group and write them to the Windows event log? In any case, none of those questions should have anything to do with me as a class library designer. I should handle the exceptions if I can do so usefully, I should wrap the exceptions if I want to make them more relevant to my direct caller, and otherwise, I should stay out of the way! And, BTW, I should document what exceptions I throw so that my callers can think about their exception handling strategies ahead of time. In my documentation, I should not only indicate which exceptions I throw (which is what a "throws" clause does in Java), but I should also indicate _why_ the exception might be thrown and perhaps give guidance as to what a caller might do about it: John Saunders
[quoted text, click to view] "John Saunders" <johnwsaundersiii at hotmail.com> wrote in message news:eGlzNqH4EHA.3472@TK2MSFTNGP09.phx.gbl... > "Mike Schilling" <mscottschilling@hotmail.com> wrote in message .. And they're likely to be a lot more specific that "IOException". >> >> Then why is the .NET framework documentation so poor in documenting >> exceptions compared to the JDK docs? > > The JDK docs naturally document what's in the throws clauses.
Exactly my point. [quoted text, click to view] >I'm not even sure whether the .NET documentation comes from Xml comments in >C# code.
[quoted text, click to view] "Helge Jensen" <helge.jensen@slog.dk> wrote in message news:41BCBD62.5010901@slog.dk... > Really, I wasn't going to comment on this holy-war, but I think I will > anyway. > > INTRO > ----- > > Checked exceptions seems like a good idea at first, which is probably why > it's included in JAVA. Unfortunatly it has a few problems, owing > sub-typing and the variance of errors, which makes it tempting to declare > every method "throws Throwable". I will shortly discuss the problem with > current implementations of checked exceptions and then propose a method > which makes checked exceptions beneficial in the way checked-exception > proponents usually argue it is. > > EXAMPLE > ------- > > Let's do an example, C# syntax (this is m*.p*.d*.l*.csharp :) with checked > exceptions as in Java. > > /** Persist objects, allow retrieval by id */ > interface ObjectStore { > int Store(Object); > Object Retrieve(int id); > }
No exceptions defined at this level? These methods can never fail? Let's start by thinking about how Retrieve, for example, can fail. 1. The id can fail to refer. 2. The object store in use was never initialized. 3. An error occurred fetching (e.g. deserializing) this object. That's not exhaustive, but it's a start. Thus: public Object Retrieve(int id) throws NoSuchObjectException, StoreNotInitializedException, RetrieveFailedException [quoted text, click to view] > Now for a specific implementation that uses a directory with files for > storage: > public class DiskObjectStore: ObjectStore { > string Directory; > Object Retrieve(int id) { > using ( Stream s = > File.Open(File.Combine(Directory, id.ToString()))) { > // fetch object > ... > } > } > } > > WHAT SHOULD WE DO WITH THE D***** EXCEPTION
Is this supposed to be hard? catch(IOException ex) { throw new NoSuchObjectException("" + id + " is not a valid object identifier", ex); }
Really, I wasn't going to comment on this holy-war, but I think I will anyway. INTRO ----- Checked exceptions seems like a good idea at first, which is probably why it's included in JAVA. Unfortunatly it has a few problems, owing sub-typing and the variance of errors, which makes it tempting to declare every method "throws Throwable". I will shortly discuss the problem with current implementations of checked exceptions and then propose a method which makes checked exceptions beneficial in the way checked-exception proponents usually argue it is. EXAMPLE ------- Let's do an example, C# syntax (this is m*.p*.d*.l*.csharp :) with checked exceptions as in Java. /** Persist objects, allow retrieval by id */ interface ObjectStore { int Store(Object); Object Retrieve(int id); } Now for a specific implementation that uses a directory with files for storage: public class DiskObjectStore: ObjectStore { string Directory; Object Retrieve(int id) { using ( Stream s = File.Open(File.Combine(Directory, id.ToString()))) { // fetch object ... } } } WHAT SHOULD WE DO WITH THE D***** EXCEPTION ------------------------------------------- (chorus: WITH THE D***** EXCEPTION) Obviously File.Open(...) can throw a FileNotFound exception, so should we catch and discard that? probably not, since we would deprive the caller of accurate information about what failed. So, we have to change the declaration of Retrieve: Object Retrieve(int id): throws FileNotFound {...} But that doesn't match the interface, and the interface declaration has to be expanded to include a "throws FileNotFound". This removes the abstractness of the interface, so you might suggest: "every implementation of ObjectStore must do some I/O, so we'll let it throw IOException". Cutting heels and clipping toes ------------------------------- This ensnaring argument hides the fundamental problem: you declared the interface to be implementation-independant in the first place. Even worse many implementations might NEVER throw an IOException, for example a test-implementation: public class MemoryStorage: ObjectStore { IDictionary objects = new HashTable(); Object Retrieve(int id) throws IOException { return objects[id]; // cannot throw IOException } } or they might throw a whole new type of exception: int id_count = 0; int Store(Object o) { int id = ++id_count; // ignore concurrency problems for now, ok? if ( id_count == 0 ) throw new OutOfNamespace(o); else objects[id] = o; } When it's NOT a feary-tale -------------------------- In the real world, what you end up with is usually either a global throws declaration in the interface (and on all the callers of the interface methods): Object Retrieve(int id): throws Exception(); Or (nervous ticks starts) every implementation doing: try { using ( Stream s = File.Open(File.Combine(Directory, id.ToString()))) { // fetch object ... } } catch ( Exception e ) { // an error occured, lot's of info in e, let's throw it away return null; } And a VERY confusing code-style (*mildly* better: Logging errors and returning null's.) This is what most JAVA programmers do, atleast in the code i've seen :) Wrapping extinguish type ------------------------ The last (and worst) alternative (which unfortunatly is done in a lot of places in .NET) is to wrap the exception: try { using ( Stream s = File.Open(File.Combine(Directory, id.ToString()))) { // fetch object ... } } catch ( Exception e ) { throw new ObjectStoreException(e); } This prevents the caller from even catching on the actual type of exception occuring, and thus robs him of a viable retry strategy (unless he wants to traverse the .Inner's of exceptions looking for the real problem. This would take HEAPS of code, especially if more than one wrapping is done). It actually removes the whole point of having Types exceptions :) *** NOTE: .NET Delegate's do exception wrapping, making catch on a delegate-invocation a VERY delicate thing to try. So, while checked exceptions have some nice properties, they really are tedious to work with when polymorphism is used, since they precisely expose the implementation differences that you wished to ignore by using polymorphism. JAVA ---- Now, zooming in on JAVA: JAVA has excepted that having every exception as checked is too tedious. In JAVA there are RuntimeException's that may be thrown *without* declaration in throws statements, and we may even declare such an exception ourselves, BUT the class heirarchy is used to indicate whether an exception should be checked or not. This is higly unfortunate, since it deprives the programmer of the ability to decide seperatly from situation to situation how "important" a specific type of exception is, whether it should be catched or not by the caller. PROPOSAL -------- If it was possible to declare "throws" statements on functions and require callers to either handle or declare the exceptions themselves (no class-hierarchy spec. of what should be checked here), AND it was possible to "uncheck" an exception, allowing the caller to knowingly pass a previously checked exception from a function as unchecked, now that WOULD be usefull. It would allow us to write the interface from above in the way we wanted, without any throws qualifier, but it would allow File.Open to declare that a FileNotFoundException could reasonably occur and that the caller should do something about it. The resulting code would be something like (with a newly invented syntax for "unchecking", could probably be MUCH ): using ( Stream s = uncheck(File.Open(File.Combine(Directory, id.ToString()))), FileNotFound) { // fetch object ... } The "uncheck" generates no code, and no catch-handler, it simply instructs the compiler that the programmer knows that the call to File.Open may cause an exception, but that should be accepted at runtime, rather the provably handled by the caller. CONCLUSION ---------- In this way the intrusion of checked exceptions may be kept to a tolerable level, and cheked exceptions declarations can be actually utilized to indicate "hey mate, this might fail, and you better have something up your sleeve if it does". --
Thanks for all your comments. Helge comments and Richard's link are very helpful. C.P. [No MCSD] [quoted text, click to view] "Helge Jensen" <helge.jensen@slog.dk> wrote in message news:41BCBD62.5010901@slog.dk... > Really, I wasn't going to comment on this holy-war, but I think I will > anyway. > > INTRO > ----- > > Checked exceptions seems like a good idea at first, which is probably > why it's included in JAVA. Unfortunatly it has a few problems, owing > sub-typing and the variance of errors, which makes it tempting to > declare every method "throws Throwable". I will shortly discuss the > problem with current implementations of checked exceptions and then > propose a method which makes checked exceptions beneficial in the way > checked-exception proponents usually argue it is. > > EXAMPLE > ------- > > Let's do an example, C# syntax (this is m*.p*.d*.l*.csharp :) with > checked exceptions as in Java. > > /** Persist objects, allow retrieval by id */ > interface ObjectStore { > int Store(Object); > Object Retrieve(int id); > } > > Now for a specific implementation that uses a directory with files for > storage: > public class DiskObjectStore: ObjectStore { > string Directory; > Object Retrieve(int id) { > using ( Stream s = > File.Open(File.Combine(Directory, id.ToString()))) { > // fetch object > ... > } > } > } > > WHAT SHOULD WE DO WITH THE D***** EXCEPTION > ------------------------------------------- > (chorus: WITH THE D***** EXCEPTION) > > Obviously File.Open(...) can throw a FileNotFound exception, so should > we catch and discard that? probably not, since we would deprive the > caller of accurate information about what failed. > > So, we have to change the declaration of Retrieve: > > Object Retrieve(int id): throws FileNotFound {...} > > But that doesn't match the interface, and the interface declaration has > to be expanded to include a "throws FileNotFound". This removes the > abstractness of the interface, so you might suggest: "every > implementation of ObjectStore must do some I/O, so we'll let it throw > IOException". > > Cutting heels and clipping toes > ------------------------------- > > This ensnaring argument hides the fundamental problem: you declared the > interface to be implementation-independant in the first place. Even > worse many implementations might NEVER throw an IOException, for example > a test-implementation: > > public class MemoryStorage: ObjectStore { > IDictionary objects = new HashTable(); > Object Retrieve(int id) throws IOException { > return objects[id]; // cannot throw IOException > } > } > > or they might throw a whole new type of exception: > > int id_count = 0; > int Store(Object o) { > int id = ++id_count; // ignore concurrency problems for now, ok? > if ( id_count == 0 ) > throw new OutOfNamespace(o); > else > objects[id] = o; > } > > When it's NOT a feary-tale > -------------------------- > > In the real world, what you end up with is usually either a global > throws declaration in the interface (and on all the callers of the > interface methods): > > Object Retrieve(int id): throws Exception(); > > Or (nervous ticks starts) every implementation doing: > > try { > using ( Stream s = > File.Open(File.Combine(Directory, id.ToString()))) { > // fetch object > ... > } > } catch ( Exception e ) { > // an error occured, lot's of info in e, let's throw it away > return null; > } > > And a VERY confusing code-style (*mildly* better: Logging errors and > returning null's.) > > This is what most JAVA programmers do, atleast in the code i've seen :) > > Wrapping extinguish type > ------------------------ > > The last (and worst) alternative (which unfortunatly is done in a lot of > places in .NET) is to wrap the exception: > > try { > using ( Stream s = > File.Open(File.Combine(Directory, id.ToString()))) { > // fetch object > ... > } > } catch ( Exception e ) { > throw new ObjectStoreException(e); > } > > This prevents the caller from even catching on the actual type of > exception occuring, and thus robs him of a viable retry strategy (unless > he wants to traverse the .Inner's of exceptions looking for the real > problem. This would take HEAPS of code, especially if more than one > wrapping is done). It actually removes the whole point of having Types > exceptions :) > > *** NOTE: .NET Delegate's do exception wrapping, making catch on a > delegate-invocation a VERY delicate thing to try. > > So, while checked exceptions have some nice properties, they really are > tedious to work with when polymorphism is used, since they precisely > expose the implementation differences that you wished to ignore by using > polymorphism. > > JAVA > ---- > > Now, zooming in on JAVA: JAVA has excepted that having every exception > as checked is too tedious. In JAVA there are RuntimeException's that may > be thrown *without* declaration in throws statements, and we may even > declare such an exception ourselves, BUT the class heirarchy is used to > indicate whether an exception should be checked or not. > > This is higly unfortunate, since it deprives the programmer of the > ability to decide seperatly from situation to situation how "important" > a specific type of exception is, whether it should be catched or not by > the caller. > > PROPOSAL > -------- > > If it was possible to declare "throws" statements on functions and > require callers to either handle or declare the exceptions themselves > (no class-hierarchy spec. of what should be checked here), AND it was > possible to "uncheck" an exception, allowing the caller to knowingly > pass a previously checked exception from a function as unchecked, now > that WOULD be usefull. > > It would allow us to write the interface from above in the way we > wanted, without any throws qualifier, but it would allow File.Open to > declare that a FileNotFoundException could reasonably occur and that the > caller should do something about it. > > The resulting code would be something like (with a newly invented syntax > for "unchecking", could probably be MUCH ): > > using ( Stream s = > uncheck(File.Open(File.Combine(Directory, id.ToString()))), > FileNotFound) > { > // fetch object > ... > } > > The "uncheck" generates no code, and no catch-handler, it simply > instructs the compiler that the programmer knows that the call to > File.Open may cause an exception, but that should be accepted at > runtime, rather the provably handled by the caller. > > CONCLUSION > ---------- > > In this way the intrusion of checked exceptions may be kept to a
[quoted text, click to view] "Mike Schilling" <mscottschilling@hotmail.com> wrote in message news:%2361y6eN4EHA.3820@TK2MSFTNGP11.phx.gbl... > > "John Saunders" <johnwsaundersiii at hotmail.com> wrote in message > news:eGlzNqH4EHA.3472@TK2MSFTNGP09.phx.gbl... >> "Mike Schilling" <mscottschilling@hotmail.com> wrote in message > . And they're likely to be a lot more specific that "IOException". >>> >>> Then why is the .NET framework documentation so poor in documenting >>> exceptions compared to the JDK docs? >> >> The JDK docs naturally document what's in the throws clauses. > Exactly my point.
And my point is that one should hire tech writers to write documentation, not compiler designers. John Saunders
Don't see what you're looking for? Try a search.
|