Showing posts with label C# vs. Java. Show all posts
Showing posts with label C# vs. Java. Show all posts

Saturday, November 26, 2011

Re-throwing exceptions.

Today we will talk about re-throwing exceptions. In many cases, after examining a caught exception, it doesn't fulfill some requirements and we must re-throw it. This is a very basic and simple action in C# but for the Java developers there is a trap. In the aforementioned scenario, in Java we would just write:
throw e;
were e is the exception we caught.
Why don't we do the same in C# and see what will happen. Below is a sample code that illustrates such situation:
   class Program
{
void m1() { m2(); }
void m2() { m3(); }
void m3() { m4(); }
void m4()
{
throw new Exception("A sample exception.");
}
static void Main(string[] args)
{
try
{
new Program().m1();
}
catch(Exception e)
{
throw e;
}
}
}
Now lets execute it and examine the stack trace:
System.Exception was unhandled
Message=A sample exception.
Source=LearningCsharp
StackTrace:
at ConsoleApplication1.Program.Main(String[] args) in C:\Path\Program.cs:line 220
What did happen here? We somehow lost the whole stack trace. Now it looks like the exception was created within the Main method – in a real life scenario that may cause many problems when troubleshooting.
How to do it correctly in C# and preserve the whole stack trace? Here is the answer:
   class Program
{
void m1() { m2(); }
void m2() { m3(); }
void m3() { m4(); }
void m4()
{
throw new Exception("A sample exception.");
}
static void Main(string[] args)
{
try
{
new Program().m1();
}
catch(Exception e)
{
throw;
}
}
}
Yes! Simple
throw;
solves the issue. Now our stack trace will look as follows:
System.Exception was unhandled
Message=A sample exception.
Source=LearningCsharp
StackTrace:
at ConsoleApplication1.Program.m4() in C:\Path\Program.cs:line 210
at ConsoleApplication1.Program.m3() in C:\Path\Program.cs:line 207
at ConsoleApplication1.Program.m2() in C:\Path\Program.cs:line 206
at ConsoleApplication1.Program.m1() in C:\Path\Program.cs:line 205
at ConsoleApplication1.Program.Main(String[] args) in C:\Path\Program.cs:line 220
...
Looks much better – we can see which method thrown the exception and thus find the source of the issue.
So Java developers – bear that difference in mind and avoid confusion when analyzing a half empty stack trace! :)

Saturday, November 19, 2011

Exception handling – multiple catch.

Let's talk about the exception handling. Just to ensure that we are standing on the same planet – multiple catch of exception is a situation when we have a method that throws more than one checked exception and we want to handle some of them separetly. The following Java code shows such situation:

import java.util.ArrayList;
import java.util.List;

class Exception1 extends Exception {}
class Exception2 extends Exception {}
class Exception3 extends Exception {}

public class ExceptionHandling {
public static void throwsExceptions() throws Exception1, Exception2, Exception3 {
return;
}

public static void testMethod() {
try {
throwsExceptions();
}
catch(Exception1 e) {
// handle Exception1
}
catch(Exception2 e) {
// handle Exception2
}
catch(Exception e) {
// handle other exceptions.
}
}
}

But what if the logic for handling Exception1 and Exception2 is the same? In this case we get a dirty code duplication. Although, there is a simple remedy for that. What we could do, is to catch a base Exception class and then branch appropriately with if-else statement as the below code snippet presents:

public static void testMethod2() {
try {
throwsExceptions();
}
catch(Exception e) {
if(e instanceof Exception1 || e instanceof Exception2) {
// Do the common handling logic for Exception1 and Exception2
}
else {
// Handle other exceptions
}
}
}

So far so good. We don't have code duplication anymore. Just a note: the above examples use Java language but they also apply to C# - we would face the same issue/remedy when coding in it.
Now you may wonder what more can be done. As for C# not much really. In Java though, there is still some room for improvement. In Java 7 there has been introduced a new multiple catch mechanism so that we can catch multiple exceptions in one catch block! The following code sample shows the solution using Java 7:

public static void testMethod3() {
try {
throwsExceptions();
}
catch(Exception1 | Exception2 e) {
// Do the common handling logic for Exception1 and Exception2
}
catch(Exception e) {
// Handle other exceptions.
}
}

Here we can see how exceptions of type Exception1 and Exception2 are handled in one catch block using the '|' operator.
Summing up – a point for Java :)

Saturday, October 1, 2011

Named arguments in C#.

So today is the day. I'm kicking off with a new series of articles in the category C# vs. Java. Let's start with a feature called named arguments. In a nutshell, it let us name arguments that we are passing when invoking some method. When it can be useful? There are a few different scenarios. First of all, it may happen that we have a method that takes many arguments of the same type. It comes as no surprise that they can get mixed easily and normally compiler won't help us as long as the passed variables' types match the ones from the method signature. Another thing is just code readability – it is much easier to go through it when we can see the variable name from the method signature next to the variable that we are passing.

class NamedArgumentsExample
{
public static void AddStock(string companyShortName, int amount, double price)
{
}
static void Main(string[] args)
{
AddStock("MSFT", 100, 150);
AddStock("MSFT", amount: 100, price: 150);
}
}

In the above code we can see 2 method invocations – the first one without using named arguments. At first glance, it may be hard to get what are the values in the AddStock method invocation for. On the other hand, in the 9th line we can see with no problem that the first value is for the amount and the second for the price of a stock that we are adding.
As for Java, there is no such feature. I'm sure you can see, even from a very simple example above that it is useful. Of course, as with everything, one shouldn't overuse it but apply in a reasonable way, in cases where it will really add clarity.
That's it for today! Hope you enjoyed the post and have a happy Sunday!!