15

I'm new in a developement for Windows 8 and C#, but I have certain experience with Java Programming.

So, when I try to make some Json parser (for example) in java, I can't do it without use a try - catch block, and this way I can handle the exception, but when I try to do the same in c# (Windows 8) and I don't use the try - catch block it works too, like this:

if (json != null)
{
        JObject jObject = JObject.Parse(json);

        JArray jArrayUsers = (JArray)jObject["users"];

        foreach (JObject obj in jArrayUsers)
        {
            ListViewMainViewModel user = new ListViewMainViewModel(
                (String)obj["email"],
                (String)obj["token"],
                (String)obj["institution"],
                (String)obj["uuidInstitution"]);

            usersList.Add(user);
        }
        return usersList;
    }

}

As I know the right way is to catch JsonReaderException, but Visual Studio never warned me on that. I would like to know if there's a easy way to know if some method throw an exception, like is on java using eclipse (it's mandatory implement try-catch block or code wont compile)

0

4 Answers 4

29

You will have to consult the documentation for that. C# lacks a throws keyword.

The term for what you are looking for is checked exceptions, and more info can be found in the C# FAQ.

Sign up to request clarification or add additional context in comments.

1 Comment

And I'm so happy that it does :)
19

In C# you are responsible for handling exceptions - which IMHO is the better way of going about it than the Java implementation. In effect, an exception should be, well exceptional, that is: It isn't something you should just always expect to happen.

Consider this weirding (yet, common) anti-pattern:

try {


} catch (Exception ex) { /* Handler goes here */ }

What exactly does that mean? Are you really going to handle every single exception that passes through here? Even stuff like OutOfMemoryExceptions? That's nuts. The only thing this sort of pattern will lead to is suppressing legitimate exceptions that really ought to bring down the application - this is fairly similar to the Java approach.

Think of an Exception as being a flag to the programmer that says 'hey, the environment just entered an impossible state'. For example, if I try to divide by zero and the system throws a DivideByZeroException, then rightly the system should alert you to this, because this is a failure - one the system can't just 'figure it's way out of' - and if you simply suppress the issue, how is that really helping? In the end this is counter-productive, in that all you're doing is masking over what is really an impossible application state. If you do this a lot in your application, then it eventually just devolves into a sludge of toxic wrong-ness. Yuck!

Exceptions also take up a lot of screen real estate. Sometimes I wish they would make the try/catch/finally blocks a little more streamlined, but then I remember that doing so would encourage people to use them more, so I repent of that position pretty quick.

Exceptions are useful programmer-to-programmer notifications saying that something you're doing doesn't make sense. Obviously we should never pass raw exceptions to the user because they won't know what to do with them. At the same time, you don't want to try to handle every single exception on the face of the earth, because 'handling' in this sense typically transforms into 'suppression', which is way worse than just letting the application fail (gracefully).

4 Comments

It should be noted, though, that (to my knowledge) Java does not force you to handle the exception, it only forces you to document the exception. That can be quite handy when the API developer was lazy and forgot to document something. All that said, I've never had an issue with it.
Cyborg is correct on this one. You do have to document exceptions, but you don't necessarily have to handle them. For example, you can just tag every method as throws (including main()) and the application will compile. That said, I am much more in favor of C#s - deal with the exception on a case-by-case basis approach than Java's deal with everything. That might be though just because I don't like Java : ) (reified generics plz!)
On top of @Cybȫʁgϟ37's excellent point, Java also has multiple subclasses of the Throwable archetype. There are Exceptions, RuntimeExceptions and Errors. Only the first category must be handled or "documented" with a throws clause, and things like SOEs and OOMEs are RuntimeExceptions, not Exceptions. It would stand to reason that if C# had checked exceptions, not all exceptions would be checked. The reason it doesn't is the reason C# can also get away with just having the Exception master throwable class and being done with it.
Fun fact: RuntimeException (unchecked) derives from Exception (checked).
19

C#, as has been mentioned, does not have checked exceptions, and thank goodness.

The idea of checked exceptions sounds great on its face, but talk to anyone who is forced to use them by language or runtime, and they'll say there are three big problems with checked exceptions:

  • They impose their will upon the consuming coder. Checked exceptions, by their definition, are expected to be handled before they are thrown out of the runtime. The runtime is in effect telling the coder "you should know what to do when I throw this, so do so". First off, think about it; you are told to expect something that happens in exceptional cases by its very definition. Second, you're expected to somehow handle it. Well, that's all well and good when you actually have the ability to address the problem the exception indicates. Unfortunately, we don't always have that ability, nor do we always want to do everything we should. If I'm writing a simple form applet that performs a data transformation, and I just want my application to die a fiery death if there's any problem, I can't just not catch anything; I have to go up all possible call stacks of every method that could throw something and add what it could throw to the throws clause (or be extremely lazy and put a "throws Exception" clause on every method of my codebase). Similarly, if my app is constructed such that I can't throw out a particular exception, perhaps because I'm implementing an interface beyond my control that doesn't specify it as a potential throwable, then my only options are to swallow it entirely and return a possibly invalid result to my callers, or to wrap the exception in an unchecked throwable type like a RuntimeException and throw it out that way (ignoring the entire checked exception mechanism, which is not recommended of course).

  • They violate SOLID, especially the Open-Closed Principle. Make a change that adds a checked exception to your code, and if you can't handle said exception, all usages of your method must either handle it or mark themselves as throwing the exception. Usages which rethrow must be handled by their own callers or they have to be marked as throwing the same exception. By making a change as surgical as calling an alternate method in a particular line of code, you now have to trace up all possible call stacks and make other changes to code that was working just fine, just to tell them your code could conceivably throw an exception.

  • They create leaky abstractions by definition. A caller consuming a method with a "throws" clause must, in effect, know these implementation details about its dependency. It must then, if it is unwilling or unable to handle these errors, inform its own consumers about these errors. The problem is compounded when the method is part of an interface implementation; in order for the object to throw it, the interface must specify it as a throwable, even if not all of the implementations throw that exception.

    Java mitigates this by having a multilevel hierarchy of Exception classes; all I/O-related exceptions are (supposed to be) IOExceptions, for instance, and an interface with methods that have IO-related purposes can specify that an IOException can be thrown, relieving it of the responsibility to specify each specific child IOException. This causes almost as many problems as it solves, however; there are dozens of IOExceptions, which can have very different causes and resolutions. So, you must interrogate each IOException that you catch at runtime to obtain its true type (and you get little or no help identifying the specific ones that could be thrown) in order to determine whether it's something you can handle automatically, and how.

EDIT: One more big problem:

  • They assume try-catch is the only way to handle a possible exception situation. Let's say you're in C# in an alternate universe where C# has Java-style checked exceptions. You want your method to open and read a file given a filename passed into it by the caller. Like a good little coder, you first validate that the file exists in a guard clause, using File.Exists (which will never throw an exception; in order to return true, the path must be valid, the file specified at the path must exist, and the executing user account must have at least read access to the folder and file). If File.Exists returns false, your method simply returns no data, and your callers know what to do (say this method opens a file containing optional config data, and if it doesn't exist, is blank or is corrupted, your program generates and uses a default configuration).

    If the file exists, you then call File.Open. Well, File.Open can throw nine different types of exceptions. But none of them are likely to occur, because you already verified using File.Exists that the file can be opened read-only by the user running the program. The checked exception mechanism, however, wouldn't care; the method you're using specifies it can throw these exceptions, and therefore you must either handle them or specify that your own method can throw them, even though you may take every precaution to prevent it. The go-to answer would be to swallow them and return null (or to forget the guard clause and just catch and handle File.Open's exceptions), but that's the pattern you were trying to avoid with the guard clause in the first place.

None of this even considers the potential for evil. A developer might, for instance, catch and encapsulate an unchecked exception as a checked one (for instance, catching a NullPointerException and throwing an IOException), and now you have to catch (or specify that your method throws) an exception that isn't even a good representation of what's wrong.

As far as what to use instead in C#, the best practice is to use XML documentation comments to inform the immediate caller using your method that an exception could potentially be thrown from it. XML-doc is the .NET equivalent to JavaDoc comments, and is used in much the same way, but the syntax is different (three forward slashes followed by the comments surrounded with a system of XML tags). The tag for an exception is easy enough to specify. To efficiently document your codebase, I recommend GhostDoc. It will only generate exception comments for exceptions explicitly thrown from inside the method being documented, however, and you'll have to fill in some blanks.

3 Comments

One nitpick: It's entirely possible that File.Exists returns true and then File.Open throws. For example, another process deletes your file between those two calls.
@piedar - Possible, but you could use a Mutex to prevent even that (if you control both processes). The point was that you might take every precaution to avoid an exception in the first place, then if it happens anyway you might want the application to die. Checked exceptions don't really give you that option, at least not without still having to ensure every layer of your call stack knows it could happen.
If you want your application to "die a fiery death", you can just exit the application in the Catch block. It's not like a misuse of exceptions by library authors prevent you from exiting your application.
1

I'm not a java developer, but from the answers here it seems as though the Java implementation is a burden to clients of those methods. However, C# missed an opportunity (Java-like or otherwise) to communicate to the caller the type of exceptional outcomes that could happen, as authored by the developer of the method, allowing me the caller to handle it appropriately.

Since this construct isn't built into the language, I would suggest to library developers that you adopt a wrapper class and use it as the return type for any methods that could go awry. Using said class as the return type in lieu of exceptions, clients can reason about what to expect when calling the method, as it is clearly defined in the method signature. Also, using the wrapper would allow a method to tell a client why something went awry in a way does not break the flow like exceptions do.

More on this subject here: http://enterprisecraftsmanship.com/2015/03/20/functional-c-handling-failures-input-errors/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.