Theme index -- Keyboard shortcut: 'u'  Previous theme in this lecture -- Keyboard shortcut: 'p'  Next slide in this lecture -- Keyboard shortcut: 'n'Introduction to C#

A complete PDF version of the text book is now available. The PDF version is an almost complete subset of the HTML version (where only a few, long program listings have been removed). See here.

7.  C# in relation to Java

C# is heavily inspired by Java. In this section we will, at an overall level, compare Java and C#. The goal of this relatively short chapter is to inform Java programmers about similarities and differences in relation to C#. It is recommended that you already have familiarized yourself with C# in relation to C, as covered in Chapter 6.

In this chapter 'Java' refers to version to 5.0 and 'C#' refers to C# version 2.0.

7.1 Types7.3 Other substantial differences
7.2 Operations

7.1.  Types
Contents   Up Previous Next   Slide Annotated slide Aggregated slides    Subject index Program index Exercise index 

In Java, types can be defined by classes and interfaces. This is also possible in C#. In addition, C# makes it possible to define structs and delegates to which there are no counterparts in Java. Java supports sophisticated, class based enumeration types. Enumeration types in C# are simpler, and relative close to enumeration types in C. - This is the short story. After the itemized summary, we will compare the two languages more carefully.

The similarities and differences with respect to types can be summarized in this way:

  • Similarities.

    • Classes in both C# and Java

    • Interfaces in both C# and Java

  • Differences.

    • Structs in C#, not in Java

    • Delegates in C#, not in Java

    • Nullable types in C#, not in Java

    • Class-like Enumeration types in Java; Simpler approach in C#

If you have written a Java program with classes and interfaces, it is in most cases relatively easy to translate the program to C#. In this material we discuss classes in C# in Chapter 11 an interfaces in Chapter 31

There are no structs in Java. Structs in C# are, at the outset, similar to structs in C. (See Section 6.6 for a discussion of C structs versus C# structs). Your knowledge of C structs is a good starting point for working with structs in C#. However, structs in C# are heavily extended compared with C. As an important observation, C# structs have a lot in common with classes. Most important, there are operations (methods) and constructors in both C# classes and C# structs. It is also possible to control the visibility of data and operations in both classes and structs. Structs in C# are value types, in the meaning that instances of structs are contained in variables, and copied by assignments and in parameter passings. In contrast, classes are reference types, in the meaning that instances of classes are accessed by references. Instances of classes are not copied in assignments and in parameter passings. For more details on structs see Chapter 14, in particular Section 14.3.

Delegates in C# represents a type of methods. A delegate object can contain a method. More correctly, a delegate can contain a reference to a method. It can actually contain several such references. With use of delegates it becomes possible to treat methods as data, in the same way as instance of classes represent data. We can store a method in a variable of delegate type. We can also pass a method as a parameter to another method. In Java it is not possible pass a method M as a parameter to another method. If we need to pass M, we have to pass an object of class C in which M is a method. Needless to say, this is a complicated and contrived way of using function parameters. - In C#, delegates are the foundation of events (see Chapter 23), which, in turn, are instrumental to programming of graphical user interfaces in C# and certain design patters, not least the Observer (see Section 24.1). For more details on delegate types see Chapter 22.

Nullable types relate to value types, such as structs. A variable of a struct type S cannot contain the value null. In contrast, a variable of class type C can contain the value null. The nullable S type, denoted S?, is a variant of S which includes the null value. For more details, see Section 14.9.

Enumeration types in both C# and Java allow us to associate symbolic constants to values in an integer type. We demonstrated enumeration types in C# in Section 6.2 of the previous chapter. In Java, an enumeration type is a special form of a class. Each enumerated value is an instance of this special class. Consequently, an enumeration type in Java is a reference type. In C# an enumeration type is a value type. - As a Java-historic remark, enumeration types did not exist in early versions Java. Enumeration types were simulated by a set of final static variables (one final static variable for each value in the enumeration type). The support of enumeration types shifted dramatically in Java 1.5: from almost no support in previous versions to heavy support via special classes. It is remarkable that the Java designers have chosen to use so many efforts on enumeration types!


7.2.  Operations
Contents   Up Previous Next   Slide Annotated slide Aggregated slides    Subject index Program index Exercise index 

Operations in Java programs are defined by methods that belong to classes. This is our only possibility of defining operations in Java. In C# there exists several additional possibilities. In this material we have devoted an entire lecture 'Data Access and Operations' (from Chapter 17 to Chapter 24) to these issues.

The similarities and differences with respect to operations can be summarized in this way:

  • Similarities: Operations in both Java and C#

    • Methods

  • Differences: Operations only in C#

    • Properties

    • Indexers

    • Overloaded operators

    • Anonymous methods

As already mentioned above, C# methods can be defined in both classes and structs. It is not possible to define local methods in methods - neither in C# or Java. The closest possibility in C# is use of anonymous methods, see below.

Properties provide for getters and setters of fields (instance variables as well as class variables - static variables) in C#. In Java it is necessary to define methods for getting and setting of instance variables. A single property in C# can either be a getter, a setter, or both. From an application point of view, properties are used as though we access of the variables of a class/object directly (as it would be possible if the variables were public). For more details on properties see Chapter 18.

Indexers can be understood as a special kind of properties that define array-like access to objects and values in C#. The notation a[i] and a[i] = x is well-know when the name a denotes an array and if i is an integer. In C# we generalize this notation to arbitrary instances of classes and structs denoted by a. With an indexer we program the meaning of accessing the i'th element of a (a[i]) and the meaning of setting the i'th element of a (a[i] = ...). Indexers are discussed in Chapter 19.

In most languages, the operators like +, -, <, and & have fixed meanings, and they only work with the simple types (such as int, bool, char, etc). We reviewed the C# operators in Section 6.7, and as it appears, operators in C, Java, and C# have much in common. In Java, the operators only work for certain predefined types, and you cannot change the meaning of these operators. In C# it is possible to use the existing operator symbols for operations in your own types. (You cannot invent new operator symbols, and you cannot change the precedence nor the associativity of the symbols). We say that the operators in C# can be overloaded. For instance, in C# it would be possible to define the meaning of aBankAccount + aTriangle, where aBankAccout refers to an instance of class BankAccount and aTriangle refers to an instance of class GeometricShape. When the existing operator symbols are natural in relation to our own classes, the idea of overloaded operators is great. In other situations, overloaded operators do not add much value.

We are used to a situation where procedures, functions, and methods have names. In both Java and C# we can define named methods in classes. In C#, we can also define named methods in structs. In C# it is possible to define non-named methods as well. As part of arbitrary expressions, we can create a function or method. Such a function or method is called a delegate. As indicated by the name, delegates are closely related to delegate types, as discussed above in Section 7.1. For more details on this topic see Chapter 22 and in particular the program examples of Section 22.1.


7.3.  Other substantial differences
Contents   Up Previous Next   Slide Annotated slide Aggregated slides    Subject index Program index Exercise index 

In addition to the overall differences in the area of types and operations, as discussed in the two previous sections, there are a number of other substantial differences between Java and C#. The most important of these differences are summarized below.

  • Program organization

    • No requirements to source file organization in C#

  • Exceptions

    • No catch or specify requirement in C#

  • Nested and local classes

    • Classes inside classes are static in C#: No inner classes like in Java

  • Arrays

    • Rectangular arrays in C#

  • Virtual methods

    • Virtual as well as non-virtual methods in C#

In Java there is a close connection between classes and sources files. It is usually recommended that there is only one class per file, but the rule is actually that there can be one public and several non-public classes per Java source file. The proper name of the source file should be identical to the name of the public class. Likewise, there is a close connection between packages and directories. A package consists of the classes whose source files belong to a given directory. - The organization of C# programs is different. In C# there is no connection between the names of classes and the name of a C# source files. A source file can contain several classes. Instead of packages, C# organizes types in namespaces and assemblies. Namespaces are tangible, as they are represented syntactically in the source files. A namespace contains types and/or recursively other (nested) namespaces. Assemblies are produced by the C# compiler. Assemblies represent a 'packaging' mechanism, and assemblies are almost orthogonal to both the file/directory organization and the namespace organization. As it appears, C# uses a much more complex - and presumably more powerful - program organization than Java. We discuss organization of C# programs in Chapter 15 at the end of the lecture about Classes.

Java supports both checked exceptions and unchecked exceptions, but it is clearly the ideal of Java to work with checked exceptions. (Unchecked exception is also known as RuntimeExceptions). It is natural to ask about the difference. A checked exception must either be handled in the method M in which is occurs, or the method M must declare that an activation of M can cause an exception (of a given type) which callers of M need to care about. This is sometimes called the catch or specify principle. The most visible consequence of this principle is that Java methods, which do not handle exceptions, must declare that they throws specific types of exceptions. Thus, the signature of Java methods include information about the kind errors they may cause. - C# does not adhere to the catch or specify principle. In C# all exceptions correspond to the so-called RuntimeExceptions in Java. Exceptions in C# are discussed in Chapter 36.

Java is stronger than C# with respect to class nesting. Both Java and C# support static nested classes (using Java terminology). In this setup, the innermost class can only refer to static members of the outer class. In contrast to C#, Java also supports inner classes. An instance of an inner class has a reference the instance of the outer class. Inner classes have implications to the object structure. Static nested classes have no such implications. In addition, Java supports local classes that are local to a method, and anonymous classes which are instantiated on the fly. C# does not.

In both Java and C# it is possible to work with arrays in which the elements themselves are arrays, and so on recursively. Using C# terminology, this is called jagged arrays, because it facilitates multi-dimensional arrays of irregular shapes. In contrast to Java, C# in addition supports rectangular arrays, in which all rows are of equal lengths. We have already discussed jagged and rectangular arrays in our comparison with C in Section 6.4.

Virtual methods relate to redefinition of methods in class hierarchies (inheritance). In Java all methods are virtual. What this means (for C#) is explained in details in Section 28.14. In C# it is possible to have both virtual and non-virtual methods. This complicates the understanding of inheritance quite a bit. There are, however, good reasons to support both. In Section 32.9 we will review a prominent example where the uniform use of virtual methods in Java runs into trouble.

Generated: Monday February 7, 2011, 12:12:57
Theme index -- Keyboard shortcut: 'u'  Previous theme in this lecture -- Keyboard shortcut: 'p'  Next slide in this lecture -- Keyboard shortcut: 'n'