站内搜索: 请输入搜索关键词
当前页面: 图书首页 > NET For Java Developers Migrating To C#

NET For Java Developers Migrating To C#

[ directory ] Previous Section Next Section

2.2 Writing Your First C# Program

We assume here that you have successfully downloaded and installed the bare bones .NET SDK on your C: drive. To compile your C# programs, you need the compiler, which is a file called csc.exe. By default, the compiler converts C# code to a shell executable file that can be run like any EXE file. Think of this EXE file as the Java runtime, with all the classes to be run put in one file. To compile your code from anywhere, you must set the directory so that the csc.exe file is in your system PATH environment variable. You can check this by typing csc at the command prompt, as shown in Listing 2.1. Note that fatal error CS2008 is really reminding you that the compiler has no files to compile.

Listing 2.1 Output from Typing csc at the Command Prompt
Microsoft (R) Visual C# .NET Compiler version 7.00.9466
for Microsoft (R) .NET Framework version 1.0.3705
Copyright (C) Microsoft Corporation 2001. All rights reserved.
fatal error CS2008: No inputs specified

You can obtain the various compiler options by typing csc /? at the command prompt. The default command, csc, should be sufficient for you to get started writing and compiling programs.

Let's write our first C# program. Open your text editor. Without typing anything in it, save your program file as MySample.1.cs. Here .cs is the file extension. At the command prompt, type csc MySample.1.cs

Listing 2.2 shows the output from the compiler. The compiler complains that the program lacks an entry point. It does not create the Listing.EXE file as you would expect. This behavior is similar to that of the JDK, which does not create a class file when you try to compile a Java file of size 0 bytes (although it does not issue a complaint). An EXE file is a stand-alone executable. For it to execute, the runtime thread or process should enter at a specific point so that it can continue execution from that point on.

Listing 2.2 Output from Typing csc MySample.1.cs (the Empty File) at the Command Prompt (C#)
Microsoft (R) Visual C# .NET Compiler version 7.00.9466
for Microsoft (R) .NET Framework version 1.0.3705
Copyright (C) Microsoft Corporation 2001. All rights reserved.

error CS5001: Program 'MySample.1.exe' does not have an entry
point defined

Now add an entry point to the file you just created. To do that, type the code in Listing 2.3 in the MySample.1.cs file.

Listing 2.3 Printing the First Argument to the Console (C#)
1 public class HelloWorld {
2   public static void Main(string[] args) {
3     System.Console.WriteLine(args[0]);
4   }
5 }

To write the preceding code in Java, create a file called MySample1.java (see Listing 2.4). (The significance of the file name is that Sun's JDK won't let you compile a file containing a public class whose name is different from its file name. Furthermore, JDK 1.3 does not allow the period symbol, and therefore the class must be MySample1 instead of MySample.1.)

Listing 2.4 Printing the First Argument to the Console (Java)
1 public class MySample1 {
2   public static void main(String[] args) {
3     System.out.println(args[0]);
4   }
5 }

Line 2 of Listings 2.3 and 2.4 is the entry point. In Java the public static void main is called by the main thread, which is initiated by the JVM. In C# the entry point is called by the CLR.

The following observations apply to the C# code:

  • In C# the class name is HelloWorld, and it is stored in a file having a different name.

  • The Main method must be static.

  • The public modifier on the class is optional. However, the modifier cannot be private or protected.

  • The modifier on the Main method is optional, and it can be public, private, or protected.

  • In C#, the Main method is somewhat overloaded. There is a Main method without any arguments. Because the Main method is an entry point, there can be only one in the class. So even though there are two Main methods梠ne with parameters and one without梐 class can have only one defined.

  • An EXE file can have only one entry point. So if your .cs file (source) has multiple classes in the same file, only one of the classes can have a Main method defined. (We will get to that topic a little later in this chapter.)

To run the C# program now, you type the following command at the prompt:

MySample.1 "Hello World"

The output of MySample.1.exe is as follows:

Hello World

Line 3 of Listing 2.3 looks similar to line 3 of Listing 2.4. In Java, the System class is found in the java.lang package, which you don't have to explicitly import. In C#, the rough equivalent of a Java package is the namespace concept. Here, System is the namespace and Console is one of the classes of the System namespace.

Importing a package in Java is supported in C# by the keyword using. Specifying using System means that your code can refer to all the classes in that namespace without fully qualifying their names. It is similar to the import facility in Java. The more general the import is, the more you will have to qualify your classes in the code. As you get more specific imports, you can avoid giving fully qualified class names to variables. In C# the same rule applies to the using keyword: The more specific the class you denote with the using keyword, the less crowded your code will be.

Listing 2.5 is an example of the namespace and using keywords in C#, and Listing 2.6 is the equivalent Java program.

Listing 2.5 Use of the using and namespace Keywords (C#)
1 namespace Test {
2     using System;
3     public class HelloWorld {
4       public static void Main(string[] args) {
5         Console.WriteLine(args[0]);
6       }
7     }
8 }
Listing 2.6 Using Packages in Java
package Test;
import java.io.*;
public class HelloWorld {
    public static void main(String[] args) {
    PrintStream out = System.out;
    out.println(args[0]);
    }
}

The package structure in Java corresponds to the way source files are stored on the disk. So a class with a package Test will be stored under the Test directory under the JVM. In contrast, the namespace structure in C# has no relation to the way source files are stored on the disk.

Also note that the using keyword works only with namespaces. You cannot write using System.Console and call the method WriteLine on its own, because System.Console is a class and not a namespace. In contrast, Java lets you import all classes of a package or a specific class of that package. This difference in behavior means that the C# keyword using is not an exact match for Java's import keyword.

So far our examples have shown one source file per class. Although this practice is the preferred Java programming paradigm, it is not required. You can have multiple classes in one Java source file, but only one of them can be public. In C#, however, you can have multiple classes in the same .cs and have all these classes be public. Listing 2.7 shows MyHelloWorldApp.cs using multiple classes in the same file. The using keyword should always precede all other namespace elements, so you can also use the Console class in the HelloWorld1 class.

Listing 2.7 Multiple Classes in the Same Source File (C#)
namespace Test {
     using System;
     public class HelloWorld {
       public static void Main(string[] args) {
         Console.WriteLine("Inside HelloWorld");
         Console.WriteLine(new HelloWorld1());
       }
     }
     public class HelloWorld1 {
       public override string ToString() {
         Console.WriteLine("HelloWorld1 ToString()");
         return "Hello";
       }
     }
}

Listing 2.8 shows the Java equivalent.

Listing 2.8 Multiple Classes in the Same Source File (Java)
package Test;
  public class MyHelloWorldApp {
    public static void main(String[] args) {
      System.out.println("Inside HelloWorld");
      System.out.println(new HelloWorld1());
    }
  }
  class HelloWorld1 {
    public String toString() {
      System.out.println("HelloWorld1 toString()");
      return "Hello";
    }
  }

Compile Listing 2.7 using the command line csc MyHelloWorldApp.cs. Then run the program by typing MyHelloWorldApp at the command prompt. You will see the output shown in Listing 2.9.

Listing 2.9 Output of the MyHelloWorldApp Program
Inside HelloWorld
HelloWorld1 ToString()
Hello

In Java, if you have two classes桝 and B梒ompiled to different files, A can call methods in B and vice versa as long as the default class loader can load the individual A and B classes from the specified classpath. For the same situation in C#, class A can access methods in the file containing class B as long as you specify at the time of compilation that the file containing class A uses classes in the namespace defined by the file containing class B. For example, the class HelloWorld2 in one source file (MyHelloWorldApp2.cs) can access the class HelloWorld1 in the file MyHelloWorldApp.cs if, at the time of compilation of MyHelloWorldApp2.cs, you specify that it uses classes in the namespace defined by MyHelloWorldApp.cs.

Listing 2.10 shows an example of how to code this. Note that the generated MyHelloWorldApp.exe file has all the metadata required to define the classes in MyHelloWorldApp.cs.

Listing 2.10 A Class That Accesses Another Class Defined in a Different Namespace (C#)
1 namespace Test2 {
2   using System;
3   using Test;
4   public class HelloWorld2 {
5     public static void Main(string[] args){
6       Console.WriteLine("Inside HelloWorld2");
7       Console.WriteLine(new HelloWorld1());
8     }
9   }
10}

Listing 2.11 shows the Java equivalent of Listing 2.10.

Listing 2.11 Java Equivalent of Listing 2.10
1     package Test2;
2     import Test.*;
3     public class MyHelloWorldApp2{
4         public static void main(String[] args){
5           System.out.println(new HelloWorld1());
6         }
7       }

The MyHelloWorldApp2.java class imports the classes in the Test package and then accesses the MyHelloWorldApp class of that package. Note that because the MyHelloWorldApp2 Java class is in a different package, it cannot have access to nonpublic classes in other packages.

In C#, to make MyHelloWorldApp2.cs run, compile it with the following command:

csc MyHelloWorldApp2.cs /r:MyHelloWorldApp.exe

To run it, call MyHelloWorldApp2 at the prompt. You will see the output shown in Listing 2.12.

Listing 2.12 Output of Running MyHelloWorldApp2.exe
Inside HelloWorld2
HelloWorld1 ToString()
Hello

An interesting point is that the HelloWorld2 and HelloWorld classes both have entry points defined. So when Listing 2.10 (containing the HelloWorld2 class) is compiled with the /r option, the resulting EXE file created gives preference to the entry point of the primary class being compiled. Also note that HelloWorld needs to be public for HelloWorld2 to access it. For more on class and method access modifiers, see Chapter 4.

It should be clear from the preceding examples that a C# EXE file is not equivalent to a Java class file. An EXE file is a self-sufficient file that contains all the information to run the entry point. It will identify and load the metadata of all the dependent classes that the entry point depends on. This obviates the need for a classpath. In Java, a single class dependent on other classes can be run provided that all the classes are accessible to the runtime through the classpath variable. You can combine several .cs files, all having entry points, and compile them into a single EXE file; you use the /m option of the compiler to specify at the time of compilation which class is to be used as the entry point.

    [ directory ] Previous Section Next Section