Building Paths in C# and Java

When it comes to build full path files strings in C# or Java, I very often see methods being reinvented again and again.

However, both framework offer utility classes to do just that for you. An it has been developed by some of the most skilled developers on the planet. How can you beat that? So stop rolling out your own path building functions!

.NET Version (in C#)

I’m always astonished that so many developers don’t know the System.IO.Path utility static class of the .NET Framework.

As an example, see this code:

String file1 = Path.Combine(@"C:\tmp\test\", "test.txt");
String file2 = Path.Combine(@"C:\tmp\test", "test.txt");

//file1 == file2

//"C:\tmp\test\test.txt"
Console.WriteLine("File: {0}", file1); 

Doesn’t matter if you forgot the “\” at the end of the directory string, it will be added. If it’s already there, it’s also fine! If you don’t know that stuff yet, have a look at the others methods available.

Now, onto Java.

Java Version

Java has the File class to do that. It’s very easy to use, but it doesn’t work the same way. You have to instantiate a new File object every time, instead of calling a static method like in .NET.

File file1 = new File("C:\\tmp\\test", "test.txt");
File file2 = new File("C:\\tmp\\test\\", "test.txt");

Now, this object is an abstract representation of the “C:\tmp\test\test.txt” file, so if you call toString() on it, you get that path as a string.

Side Notes

Two interesting things I noticed while writing this.

First, a difference between .NET and Java path creators. The .NET Path.Combine will return only the second string if it starts with the “\” character, while the Java File class will ignore it. the .NET class probably assumes that it’s a relative path, while the Java class ignores it.

Second, if you try to create an instance of the .NET Path class, Visual Studio will give you the following error message: “Cannot create an instance of the abstract class or interface ‘System.IO.Path’”. Once you tried to build, if fails and the error message changes to “Cannot create an instance of the static class ‘System.IO.Path’”. It’s clearly related to Visual Studio, but it’s the first time I notice that behavior (the first error message was quite suspicious with the “abstract class or interface” thingy). Anyway, Visual Studio warns you that it cannot be done, which is the important thing, then it refines it’s error message based on the output of the compiler.

Constant in Eclipse and in Visual Studio

Java naming conventions states that constants, declared as static and final, must be named all uppercase. Eclipse will automatically turn these guys in blue and italic. Here is an example of what it will look like in Eclipse:

public class Sandbox {
    public static final String CONSTANT_VALUE = "Hello World!";

    public static void main(String[] args) {
        System.out.println(CONSTANT_VALUE);
    }
}

That’s pretty neat. You cannot miss a constant, even if it is not fully qualified (it has to be if it is from another class, of course).

According to Microsoft’s naming conventions, constants in C# (that use the const keyword, being compile time constants) have to be named using Pascal Case. Visual Studio doesn’t color it any special way, meaning that if it is not qualified, you cannot know if it is a constant, a propertie, a variable…

Here is what it looks like:

class Sandbox
{
    const String ConstantValue = "Hello World!");

    static void Main(string[] args)
    {
        Console.WriteLine(ConstantValue);
    }
}

I find this a bit disturbing, as constant should always be easy to recognize. Well, at least that what I think. I was not able to find any option in Visual Studio to change this. A good start is to always fully qualify constants, in this case using Sandbox.ConstantValue (same advice goes for this keyword, I always use it, even when unnecessary).

You can find some more details on this subject here on stackoverflow.

Java Inheritance VS C# Inheritance

This topic is very basic, but I felt like writing something on simple subjects that may be misunderstood. It is also a good excuse to go in language specifications and read all the details that most of the people don’t like to read… As I’m working in Java now, I quite like to compare the two languages to see where are the differences and make sure I don’t do any silly mistake.

So, when it comes to inheritance, there is a big difference between Java and C#.

Java Inheritance

In a Java subclass, you can override any method of the superclass. The method that is to be called is always determined at run time. So for example, if you write code like this:

public class Parent {
    public String sayHello() {
        return "Hello from Parent";
    }
}

public class Child extends Parent {
    public String sayHello() {
        return "Hello from Child";
    }
}

If you create a new instance of the Child class, when you call the sayHello() method, it is always the Child one that will be called, no matter what the declaration class is. So, you can teat an instance of Child as an instance of Parent, but the methods called will be the ones from Child (if they are overriden, of course).

Code like this:

Parent o = new Child();
System.out.println(o.sayHello());

will output this:

Hello from Child

C# Inheritance

In C#, things are a bit different. C# language needs to be told which method can be overriden (declared as virtual), and which method overrides (declared as override). So to have the same behavior as Java, C# code has to look like this:

class Parent
{
    public virtual String SayHello()
    {
        return "Hello from Parent";
    }
}

class Child : Parent
{
    public override String SayHello()
    {
        return "Hello from Child";
    }
}

If the virtual and override are omitted (or just the override, actually), then it is the Parent’s method that is executed when the Child object is declared as Parent.

In C# language specification, there is a clear explanation on how is behaves:

In a virtual method invocation, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. In a non-virtual method invocation, the compile-time type of the instance is the determining factor.

Summary

To sum it up, in Java the method called will be determined by the instantiation class, while in C# it will depend on how the class and the calling code is written. C# gives you much more flexibility, but it is more complicated and the capacity for a class to override a method is determined by its parent class. With Java, you loose the ability to call the parent’s method, but is that very useful? On the other hand, C# ensures that if you don’t want a method to be overriden, it won’t be.

Oh and we forgot to talk about the new keyword in C#. I never came across code that used it, but a nice description is given here.

Boolean Logical Operators and Boolean Conditional Logical Operators

I’m often amazed that most programmer don’t know that in C# and in Java you can use the simple & and | as logical operators. It seems than most people don’t event know that they exist!

But what’s the difference between these simple and double logical operators?

Back To Basics

Let’s see in the C# language specifications:

The result of x & y is true if both x and y are true. Otherwise, the result is false.

The result of x | y is true if either x or y is true. Otherwise, the result is false.

Now let’s have a look in Java language specifications:

For &, the result value is true if both operand values are true; otherwise, the result is false.

For |, the result value is false if both operand values are false; otherwise, the result is true.

It’s pretty clear, it does what most of the people would expect them to do, and and or operations.

But, then, what are those && and || that most developers use everywhere, wasting bytes like there’s now tomorrow?

Again, specifications are there to give full explanations.

In C#:

The && and || operators are conditional versions of the & and | operators:

  • The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is true.
  • The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is false.

And in Java:

The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true.

The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.

Tadaaaam! Now it makes perfect sense, doesn’t it? These operators that most of the people use everywhere are smart and only evaluate the right-side if it is of any use (if left-hand side is true for and, if left-hand side is false for or).

So, let’s give a small example of how this can be useful. Let’s pretend you have an object that has a member that can be null. With these operators, you can test it without any fear of the dreaded NullReferenceException or NullPointerException. Here is a small piece of C# code that shows the point:

var p = new Parent { Name = "Father" };
p.Childs = new Person[] { new Person() { Name = "Son" } };

if (p.Childs != null && p.Childs.ElementAt(0).Name != null)
{
    Console.WriteLine("First Child's name: {0}",
        p.Childs.ElementAt(0).Name);
}

If Child collection was left null, this code would still work even though p.Childs.ElementAt(0) would normally throw an ArgumentNullException. As p.Childs != null returns false, the right-hand operand is not evaluated so no exception is thrown.

Now, as you may say “Well in this case, why does it matter? Let’s use && and || everywhere, so we make no mistake!”. Technically, it is true. However, as one of my University teacher said:

Les gens qui utilisent les opérateurs conditionnels booléens partout sont des gens qui ne savent pas ce qu’ils font.

Translation: “Peoples who use conditional logical operators everywhere are peoples that don’t know what they’re doing”.

Of course, his point was that you should understand the code you are writing and that you should know when which part of an expression can be evaluated. I have no clue if there is a performance gain when using non conditional operators, nor if there is any compiler optimization of any kind.

The Third Operator

There is also a third operator in both languages: ^.

In C#:

The result of x ^ y is true if x is true and y is false, or x is false and y is true. Otherwise, the result is false. When the operands are of type bool, the ^ operator computes the same result as the != operator.

In Java:

For ^, the result value is true if the operand values are different; otherwise, the result is false.

I’v never seen this operator used. As pointed in C# specification, this operator has the same result as the != operator.

And, of course, it doesn’t make any sense to have a ^^ operator, as both operand have to be evaluated in all the cases…

Something I don’t like about C#

In general, I prefer C# over Java. It’s a matter of personal taste, but I find C# more elegant, even if they are very close to each others. But there is something about C# that always bugs me: the way inheritance is declared.

If we look at this code:

public class FooBar : Bar, Foo
{
}

Apart from Visual Studio’s tooltip that helps you, how do you know if Bar is a interface or a class? It can be both, and there is no way of telling.

We obliviously know that Foo is an interface, as only one base class can be defined and it has to be right after the ":" character (see the Class base specification of the C# language).

A class declaration may include a class-base specification, which defines the direct base class of the class and the interfaces implemented by the class.

class-base:
:   class-type

:   interface-type-list

:   class-type   ,   interface-type-list

interface-type-list:
interface-type

interface-type-list   ,   interface-type

But what about Bar? According to the language specification, it can be either an class or an interface, we cannot know just by looking at it. Guidelines for Names that states that interfaces should be prefixed with I, so we could assume that it is a class. However, in this particular example, Foo is an interface for sure but is not prefixed with I, so we cannot assume that Bar is an interface, right?

Now, if we look at Java’s syntax, it is much neater:

public class FooBar extends Bar implements Foo
{
}

Looking at this, there is no doubt that Bar is a class and Foo is an interface (see Java Language Specification parts on Superclasses and Superinterfaces). Even if the developer gave crappy names, we can sort out what is an interface and what is a class.

Now, that said, Visual Studio will always tell you if it is a class or an interface. but if you open the source file with something else than a smart IDE? Notepad for example? I think that the language should speak for itself and not rely on naming conventions. With C#, you can have a doubt, while with Java there is none.

But I still love C# for everything else, I think…