AddThis Social Bookmark Button

Print

Conversational C# for Java Programmers
Pages: 1, 2, 3

Comparative anatomy

Source Files

Let's dissect this program, starting with the files that the source code goes into. In Java, each class needs to exist in a like-named file (usually with the like-named extension .java) -- there are, of course, exceptions with class visible and inner classes, as those are defined within another class's .java file. C# does not have this, or any, restriction when it comes to defining classes, even when they are in different namespaces -- any part of a C# program may exist in the same .cs file, so as to form a self-contained unit.



Naming Convention

Java programs almost always follow one standard convention for naming: mixed-caps, called camel cased. (Conventions are not imposed by the compiler, but simply appear in the Java Language Specification and provide a style that programmers use and become familiar with within certain languages -- as always, there are author-personal exceptions to these rules.) Mixed-caps style doesn't use spaces or underscores between logical splits in a name, but instead uses capital letters. Object names typically have their first letter capitalized and then follow wimpy caps for the rest of the name, for example ThisIsAnObjectName. The first letter of a method, or variable, is usually in lowercase, followed by the capitalization of all other logical splits (thisIsAMethodName and thisIsAVariableName). Often, named constants (static final variables) break from this convention and are usually declared in Java by having names in all capital letters such as THISISACONSTANT.

C# follows this mixed-caps style, except that method names typically also capitalize their first letter. This is often referred to as Pascal cased. It is the standard to have the .NET Framework use Pascal case for object, method and property names, but use camel casing for parameters.

Packages/Namespaces

Java packages place classes into different author-defined namespaces for organization and readability; the rule of thumb is that related classes go into the same package (and subpackages contain closely related classes within a package, etc.). Coders can know to look in a specific package to find classes that can provide related functionality. In Java, to use classes within a package, either the "fully qualified name" (i.e. java.io.BufferedReader) can be specified within the code, or the entire package or specific class can be imported into the namespace using the "import" statement at the top of the class's source. All of the standard classes provided by the JRE are partitioned out into the java package.

C# has a similar name-partitioning scheme. To delimit different namespaces, a namespace block is specified. In the Hello.cs file, the namespace com.oreilly.hello block defines that all code within the braces are to be assigned to the com.oreilly.hello "package." What is not illustrated in the above example is that these namespaces may be nested. For example, the above namespace may have been defined as

namespace com {
  namespace oreilly {
    namespace hello {
    }
  }
}

This allows different structures to be placed within different namespaces while within the same source file. C#'s "using" statement brings an entire specified namespace into the program's space; it does not have the exact same functionality as Java's "import" statement, as it cannot bring a specific object into the program's namespace.

Constructing an Object

All classes in C# descend from the System.Object class, just as all classes in Java descend from the java.lang.Object class. And just as in Java, if a class is simply extending Object (the default), then it is not necessary to specify it in the source code. When extending a class, the use of ":" is required (in the place of the "extends" keyword in Java). In the above example, the C# Hello class's fully qualified name is com.oreilly.hello.Hello, as it is defined in that namespace. What is not shown above is how to implement interfaces -- Java provides a very clean way of differentiating when the code is extending another object (via the "extends" keyword), and when the code is implementing an interface (via the "implements" keyword). Java programmers may get annoyed with C# as it muddles the two together: interfaces may also be placed after the colon, and the compiler will only demand that the class it extends (if the class directly extends another) is the first listed after the colon.

class ClassName : ExtendedClass, Interface1, Interface2, ...

The default access modifier for classes in C# is to make them "internal," meaning they are not accessible from any other object outside the .cs file in which they are defined. The more familiar "public," "private," and "protected" modifiers are provided along with a fifth "protected internal" modifier which is the union of "protected" and "internal" properties (the modified can be accessed from a class which extends the enclosing class, or from within the file in which it has been defined). In the Hello example above, both the Java and the C# class are defined to be "public," although they do not need to be. Neither class provides functionality that any other object may wish to use -- they simply provide the proper signature so that the run-time environment may execute them.

[Ed. Note: This paragraph is no longer completely true as of current versions of C#. While the default access modifier for C# class statements is "internal". Internal means it is only visible within the assembly in which it is defined, not just within the .cs file as the author previously stated. The default access modifier for members of the class is private (not internal).]

Providing Entry and Exit Points

In order for the runtime environment to load and start a class, it needs to know where to begin. The Java language has the programmer define a public static void main( String[] args ) method so that the JVM may be able to pass the command line arguments into that method and start the program. In order to be more flexible (and more C-like), C# allows the programmer three different method signatures for the entry point. The simplest one is the public static void Main() method, followed by the public static void Main( string[] args ) and the public static int Main( string[] args )" methods. The last two signatures have the ability to take in the command line parameters passed into the program, and the third has the ability of returning an exit code.

But just like Java, having an entry point that does not have a return value does not mean that the exit code of the program cannot be set. In Java, the programmer can call System.exit( int code ) with the value to exit with. A C# programmer can set the ExitCode property in the System.Environment class and when System.WinForms.Application.Exit() is called, the value of ExitCode is returned to the run time environment.

Pages: 1, 2, 3

Next Pagearrow