"As a language, C# certainly has a lot of potential. Whether C# can overcome resistance from the Java community remains to be seen though.
" |
C#, part of the new Microsoft .NET platform, bears all the hallmarks of a great language. Strikingly similar to Java, the language includes some of the best attributes of modern object-oriented languages, as well as adding a few new tricks of its own. In this second part of our series (see
First Impressions of C#: Java Killer or Java Wannabe?
,) I’ll cover some of the important new features of C#, along with offering a balanced view of its drawbacks.
Automatic Garbage Collection
One of the coolest features of Java is its support for automatic garbage collection (see
Understanding Automatic Garbage Collection
.) Rather than have to manually allocate memory (Do you remember the days of C and the
malloc |
Support for Interfaces
Like Java, the C# language will support interfaces. Interfaces allow programmers to define a set of method signatures that must be implemented by a class. Classes that implement an interface can then be cast as that interface. For example, the Java
Thread |
Runnable |
Runnable |
Defining an interface in C# is no different to defining one in Java. However, the
implements |
public interface Task
{
public void doTask();
}public class Nothing : Task, SomeOtherClass
{
public void doTask()
{
System.Console.WriteLine ("Doing nothing….");
}
}
Listing 1. Interfaces in C# are extended, not implemented.
Type-safe Variables Automatically Initialized
If you remember the bad old days of C, you’ll remember that variables weren’t type-safe. If you had a pointer reference, you could treat that memory as an
int |
char |
Support for COM and the Windows API
C# includes support for the Component Object Model (COM) and the Windows API from the ground up. In fact, C# doesn’t even come with its own class library! Instead, C# relies on the same class libraries of other Microsoft-supported languages, such as C++ and Visual Basic. In this area, C# excels over Java. Even though native code can be accessed through J/Direct and the Java Native Interface, this is not an easy process. If C# makes accessing native code, and COM objects, as easy as in C++, it will have a clear advantage over Java.
Versioning
As projects become more complex, and team sizes grow, the need for versioning becomes significant. Developers modifying classes and adding new methods can cause all sorts of problems when method signatures collide or change. If a developer adds a new method to a base class, it may match the method signature in a subclass. Conversely, if a developer changes a method signature in a base class (changing parameters or method name), then subclasses no longer override it — causing a silent error that is extremely hard to detect.
To prevent these errors, C# requires method overriding to be explicit, so that compilers can generate warnings and errors that signal a problem. When overriding a method, the new override keyword is used. For example, consider the following code snippet, which illustrates its use
class NetworkServer
{
public virtual void start(int port)
{
// initialize server …..
}public virtual void stop()
{
// shutdown server …..
}
}class DebugServer : NetworkServer
{
public override void start(int port)
{
System.Console.WriteLine("DEBUG EVENT – Server initializing");// initialize server
}public override void stop()
{
System.Console.WriteLine("DEBUG EVENT – Server shutting down");// shutdown server
}}
Listing 2. Use of the override statement (highlighted in bold) for versioning
Delegates
Delegates are a replacement for the old function pointer of C++. Think of delegates as an object-oriented function pointer, that points to a specific object’s method. At runtime, the actual class of the object doesn’t need to be known, so objects of different classes can be substituted providing they adhere to the same method signature. You could iterate through a whole set of delegates, invoking them without caring which object they belong to. Of course, dynamic binding of methods (known as polymorphism) has been around in languages like Java and C++ from the very beginning, but delegates differ in that only a reference to the method of an object is being passed, not the object itself. This means you can limit access to other public member variables and methods and expose only the method to which a delegate is bound. When carefully used, this will be a really cool feature.
Flaws in the C# Language
So far, I’ve covered the strengths of C#. However, no evaluation of a language would be complete or fair without looking at its weaknesses, and there are quite a few. The following are some of the most important flaws:
- use of pointers and "unsafe" code
- few thread-specific language statements
- lack of portability.
Use of Pointers and "Unsafe" Code
Microsoft was reluctant to ditch support for pointers. A purely object-oriented language, like Java, would be far safer than one that allows pointer manipulation and direct access to memory. As a partial concession, C# includes a new keyword, called
unsafe |
Few Thread-specific Language Statements
While it’s certain that C# will support multithreading through the Windows API, it will place responsibility for writing thread-safe code on the programmer. Java includes the
synchronized |
lock |
volatile |
Lack of Portability
One of Java’s chief claims to fame is cross-platform portability. While the folks at Redmond must have been worried that Java would topple their stranglehold over the operating system market, in the five years it’s been around that hasn’t happened. However, the numbers of Java developers have swelled, because of the ease in deploying software to multiple platforms. An attempt has been made by Microsoft to create a semi-portable language, in the form of C#.
Microsoft has created what it terms the "Common Language Subset" (CLS), which allows CLS-compliant languages and class libraries. That means, in theory, that a CLS-compliant interpreter written for Unix could run C# code, just like Java bytecode is executed inside a JVM. However, with the reliance of C# on the COM architecture, C# applications are mostly limited to running on the Windows .NET platform — particularly if they take advantage of Windows-specific features. While it may be possible to port or translate "generic" code that doesn’t access native features, just like in Visual J++ 6.0 developers will find it very tempting to write for only Windows machines. Java, on the other hand, lends itself to writing portable code, and provides only limited access to native code via the Java Native Interface (JNI).
Summary
As a language, C# certainly has a lot of potential. For existing C++ developers, there are some great language features that, until now, were enjoyed only by those in the Java camp. For existing Java developers, of course, there’s the prospect of writing fast applications that harness all the potential of the Windows API. Whether or not C# can overcome resistance from the Java community and become a real threat remains to be seen though. The likely scenario is that Windows C++ developers and some Java coders will migrate to C#, some will use both, and most Java developers will remain loyal. Java’s days aren’t numbered, but neither are Microsoft C#’s.
About the Author
David Reilly is a software engineer and freelance technical writer living in Australia. A Sun Certified Java 1.1 Programmer, his research interests include the Java programming language, networking & distributed systems, and software agents. He can be reached by e-mail at java@davidreilly.com or via his personal Website.