C# Strikes a Chord

When Microsoft recently announced its new programming language, C# (that's C-Sharp), industry watchers immediately started speculating about the pedigree of the proposed language. Was it the son of Java? Or a closer relation to its C++ cousin in Visual Studio? The official line from Microsoft is that C# is a C/C++ derivative.


December 01, 2000
URL:http://www.drdobbs.com/c-strikes-a-chord/184404409

C# Strikes a Chord

C# Strikes a Chord


by Jacques Surveyer

Jacques Surveyer is a web consultant; he chats computing at www.inforamp.net/~jbsurv

When Microsoft recently announced its new programming language, C# (that's C-Sharp), industry watchers immediately started speculating about the pedigree of the proposed language. Was it the son of Java? Or a closer relation to its C++ cousin in Visual Studio? The official line from Microsoft is that C# is a C/C++ derivative. C# clearly borrows from Bjarne Stroustrup's C++, but it also draws much from James Gosling's Java. I have carefully read the three reference documents for the languages written by their creators — The C++ Programming Language: Special Edition by Bjarne Stroustrup; Java Reference by James Gosling and C# Reference, by Anders Hejlsberg. Using these sources I will compare the languages and attempt to uncover a family genealogy.

    What do you think about C#?  
  Share your views in our forum.  

Given the distinguished heritage, I really expected to find some interesting OO speculation and design criteria espoused by the three language designers. But to my surprise such comments were held to a minimum. Rather, like Sir Isaac Newton's quote cited in Java Reference, "If I have seen further it is by standing on the shoulders of Giants," all three designers give a flourishing nod to their predecessors (C in the case of C++, C++ in the case of Java, and C/C++ in the case of C#) and then are up and about explaining the details of their respective languages.

Nonetheless it is possible to get glimpses of what design criteria were used in each case. Bjarne Stroustrup describes C++ as " a general purpose programming language with a bias towards system programming that is a better C; supports data abstraction; supports object-oriented programming; supports generic programming." James Gosling is, like his language, a bit more terse: "Java is a general purpose, concurrent, class-based, object-oriented language." And Anders Hejlsberg declares "C# is a simple, modern, object oriented, and type-safe programming language derived from C and C++."

Next: Code Comparison

1 | 2 | 3 | 4 | 5 | 6

C# Strikes a Chord

C# Strikes a Chord

Code Comparison


So C++, Java, and C# are all defined as general purpose object-oriented languages. Superficially the languages look very much alike because they use the same variable naming conventions, comment structure, and code block delimiters, "{}". Our HelloWorld programs shown in Example 1 exhibit these surface similarities, but there are also some notable differences.

First, C#'s Console I/O and data formatting changes follow neither the C++ nor Java models. From RPG thru Cobol, Fortran, Basic, C, C++, Visual Basic, Java, and now C#, programmers have come to expect with each new language that they must relearn the simplest of tasks — character input and output. Unfortunately, C# did not break with this venerable programming tradition.

Second and perhaps of even more importance, the basic structure of C++ differs from C# and Java. The latter two languages are class based. You cannot create a program in either C# or Java without at least declaring one class — HelloWorld in this case. Moreover, this class, HelloWorld, implicitly derives from the same root class, Object. Again, Java and C# follow the same single-inheritance design strategy, as opposed to the multiple inheritance allowed in C++. This is not the only area in which C# follows Java much more closely than C++. But as we shall soon see, C# also reinstates some C++ features that James Gosling trimmed out of the compact, run-anywhere Oak that became Java.

And finally, C# has its own distinctive features. Anders Hejlsberg angled for a programming language with greater interoperability with other components and languages as a top design goal. So, let's compare the languages.

 

Example 1
Hello World in C++, C#, and Java

 
  #include <iostream.h>
// This is a comment in C++ code

int main(){
 for(int ii = 1; ii <= 100; ii++)
     cout <<"Hello World, repeated another " << ii << " times. " << '\n';
}
   


 
 

// This is a comment in C# - C Sharp code

using System;
class HelloWorld{
  static void Main(){
   for(int ii = 1; ii <= 100; ii++)
     Console.WriteLine("Hello World, repeated another {0} times. ", ii);
  }
}


 
  // This is a comment in Java code

class HelloWorld{
  public static void main(String[] args){
    for(int ii= 1; ii <= 100; ii++)
      System.out.println("Hello World repeated another " + ii  + " times.");  
  }
}


 

Next: Syntax Comparison

1 | 2 | 3 | 4 | 5 | 6

C# Strikes a Chord

C# Strikes a Chord

Syntax Comparison


Table 1 summarizes the comparison between C++, Java and C#. We have deliberately put C# in the middle column flanked by C++ and Java to make it easier to see in what direction C# leans with regard to each feature. The Executable Environment and Language APIs are also included in the comparison. These are as important as the language's syntax in determining how the programming language gets used. In fact, this has always been true with languages. The choices between interpreted versus common .obj files and linking options have determined the flexibility and critical runtime performance of a number of languages. In addition, the availability of a common set of subroutine libraries and system APIs have been a selling point for languages from Fortran to C to Smalltalk and now Java and C#.

The first thing you note is that similarities between C++, Java and C# go well beyond HelloWorld. The number of common or synonymous keywords, operators and flow of control statements never drops below 75 percent. And why not? Pascal derived much syntax from Algol, and of course C++ from C. That programming language designers are following Isaac Newton's suggestion and deriving their syntax from a common starting base is no small boon to programmers. Already pressed with unremitting change in hardware and software technology, anything that helps to keep a language familiar and easily learned is welcome.

There may seem to be some anomalies among the 75-percent-common syntax features. Even though C# has only 52 operators, because C++ has about a dozen keyword equivalents to character operators (such as bitand == "&" and bitor == "|") it has a number of duplicate operators matching C# equivalents. The result is that 59 C++ operators map into some (but not all) of the 52 C# operators. Note also we have called these "common or synonymous". Thus we consider C#'s is operator to be substantially synonymous with Java's instanceof. Perhaps the best approach is to highlight the notable differences in syntax between the two languages.

 

Table 1
Comparison of C++ and Java to C# 

  Syntax Features

C++

C# Java
  Program code to intermediate code No Yes Yes
  Single inheritance, all objects implicitly derived from master class, Object No Yes Yes
  Unicode for char, String, identifiers No Yes Yes
  Uniform implementation of primitive type bitsizes No Yes Yes
  All primitive types derived from Object No Yes No
  Allows pointers, explicit memory mgmt. Yes Yes Simple, =null
  Struct, enum Yes Yes No
  Common or synonymous keywords to C# 56 of 74 69 of 69 46 of 50
  Flow of control statements 9 7*
  Common or synonymous operators to C# 59 of 70 52 of 52 47 of 56
  Explicit exception handling with throw, try-finally-catch  Yes, no finally Yes Yes
  Operator overloading Yes Yes except for = No
  Preprocessor statements (#define etc) Yes Yes No
  In-processing attributes No Yes No
  Parameter options in, out, ref, params No Yes No
  Compiler aids/hints asm, inline, register Yes No No
  Templates, generic programming Yes No No
  Executable Environment
  Open, cross-platform intermediate language code No Promised Yes
  Garbage collection and memory management No Yes Yes
  Type safe assignments, method invocation, initializations, array bounds checks Some Yes Yes
  Explicit invocation sequence for applets, servlets, beans/components No No Yes
  Fine-grained security of access/operation No Yes Yes
  Disassembly and metadata sharing Some Yes Yes
  JIT-Just In Time compilation and performance enhancers No Yes Yes
 Language API
  Number of standard classes and methods 100's 100's 1000's
  Open source API Some To be decided All
  Standard container, math, I/O classes, etc Yes Yes Yes
  Direct tie to XML for documentation No Yes Yes
  Direct use of XML for interface and remote procedure calls No Yes No

* 7 are identical: no foreach, goto

Next: Notable Differences

1 | 2 | 3 | 4 | 5 | 6

C# Strikes a Chord

C# Strikes a Chord

Notable Differences


As previously stated, both C# and Java use single inheritance, but both allow deriving additional method functionality from a commonly derived interface (see Example 2 and Figure 1 below for more details). C# and Java stick together as well on use of Unicode and precisely defining the bit-size of all primitive types like char, short, int, float, double and others (C++ allows them to be implementation dependent). But C# then swings toward C++ and uses struct  and enum  (but not union) in a departure from Java. In C#, struct is the same as class, except they cannot be derived and they are passed by value instead of by reference. The result is some performance tuning options for programmers — struct provides a memory savings, but at the cost of the possible overhead of call by value, whereas the opposite is true for class.

Example 2: Interface and unsafe code

// Demo C# program to illustrate interface and unsafe code
using System;
using System.Collections;
// An interface defines one or more abstract methods
interface Header{
  void saythis(String s);
}
// Next, Demo derives Header
class Demo : Header{
// so Demo must supply definitions of all Header's methods
  public void saythis(String s){
    Console.WriteLine(" Header says {0}", s);
  }
  public static void Main(){  // Our "main" routine
    int ii = 0; //define this in Garbage Collection space
    unsafe {
     //Test our interface first
      Demo DemoHeader = new Demo();
      DemoHeader.saythis("'Nice to be among the Magnolias again' !");
     // Now demo 'unsafe' coding practices
      IDictionary varEnviron = Environment.GetEnvironmentVariables();
      Console.WriteLine("\n There are {0} Environment variables", varEnviron.Keys.Count);
      fixed(int* ip = &ii){   //so fix 'ii' to be Garbage Collection secure with this block
        foreach(String eString in varEnviron.Keys){
         *ip += 1;
         Console.WriteLine(" {0} {1} = {2}", *ip, eString, varEnviron[eString].ToString());
        }
      } // End of fixed block
    } // End of unsafe block
  }
}
Figure 1. Output from code in Example 2.

But the biggest change for C# is that it allows use of pointers. The code has to be marked with an unsafe keyword as shown in Example 2. The mechanism is primarily to provide for interfaces to COM and Win32 APIs. With the need to declare variables as fixed - to be excluded from garbage collection explicitly, even when the variable is declared within an unsafe block - I expect unsafe coding will be kept down to a minimum. Of more interest than the return of pointers will be the return of C++ operator overloading and preprocessing statements.

The curious thing with operator overloading is that unlike in C++, the assignment operator cannot be overloaded. When a binary operator is overloaded, the corresponding assignment operator is also implicitly overloaded. For example, an overload of operator * is also an overload of operator *=. So in C# code:

public Matrix operator *(Matrix a, Matrix b){ //Code for Matrix multiplication}
Matrix A; Matrix B;
.... //After initializing, do Matrix multiply
A * B; // is really equivalent to A *= B

So all binary operator overload methods are destructive of their lefthand side operands. Not quite what you expected; however restoration of pre-processor statements like #define and #if are also unexpected but a bit more of a pleasant surprise.

Also interesting are the parts of C++ syntax that were dropped by both C# and Java. We have already mentioned multiple inheritance and should mention friend functions. Also, a whole range of compiler hints like register, inline, auto and others have not been adopted by either C# or Java. But the biggest omission by far is all of the templates and generic programming constructs in C++. There may be two reasons for this. First, the syntax is brutal, as the following line of C++ testifies:

template<class Ch, class Tr, class A> basic_string<Ch, 
    Tr, A> operator+(const basic_string<Ch, Tr, A>&, const basic_string<Ch, 
    Tr, A>&);

Second, C# has unified primitive types under Object. So now using a mix of primitive and objects together, for example in container classes or GUI routines, is simplified enough to warrant omission of templates.

But just as interesting is what has been retained in all three languages. The basic primitive types are all there. C# adds sbyte, uint, ulong, ushort, plus decimal. The flow of control statements are nearly identical, with C# restoring the foreach and goto. Hurrah: I think the goto has been unfairly maligned. Which is conceptually simpler: Java's labeled break or a goto ? Meanwhile, the three languages have stuck pretty close together on what the operators should be and do. And as we noted at the outset, more than 75 percent of the keywords are either common or have synonymous meanings. This lowers the learning curve — no small blessing these days.

Next: Microsoft's New Executable Environment

1 | 2 | 3 | 4 | 5 | 6

C# Strikes a Chord

C# Strikes a Chord

Microsoft's New Executable Environment


Probably the biggest change regarding the new Microsft.NET framework is the development of a brand new executable environment for all Microsoft compilers and scripting languages. It's called the Common Language Runtime (CLR), and on this point I have to be careful. I can't call it an interpreter or a virtual machine or the output p-code nor bytecode — heaven forbid! The output of all Visual Studio.Net languages will be either a Common Intermediate Language (CIL) file or an .EXE; but not your ordinary run of the mill .EXE. The .EXE now includes more metadata describing data and methods, creator and security permissions inlcuding an optional PKI signature, location of references to objects and exception handling tables. In turn, the CLR environment can provide both managed and unmanaged code execution. Unmanaged code execution is used to interface to COM, COM+, Win32, plus your own existing .DLL components and runs code after setup with the same performance and security they had before. Managed code execution provides the following additional services:

Microsoft hopes to address three pernicious problems. 1) rid itself of the security leaks presented by scripting, macro languages and its own passive, I-know-who-did-this enforcement ActiveX security procedures (think ILOVEYOU, Melissa Virus, and rogue ActiveX respectively); 2) eliminate .DLL Hell with side-by-side versioning; and 3) reduce the embarrassment of e-Registry dysfunction with each executable now being responsible for permissions and runtime attribute setting.

The new .NET Framework applies not to just C# but also all the other Microsoft compilers and scripting languages. However, C# is not only the key development language for the framework but also its guinea pig. According to Microsoft officials, C# is often the first language, even before VC++, used to test out some of the new CLR features. Also the new CLR executable environment goes well beyond the Java Virtual Machine. It is especially innovative in its ability to support existing COM and other components while interfacing to a wide range of languages (Microsoft has demoed COBOL, Component Pascal, Eiffel, Haskell, ML and Scheme running and taking advantage of the new CLR executable environment). Nonetheless Microsoft fails to give credit where credit is due. The JVM with its garbage collection, security, and runtime exception checking as well as various modes of compilation and execution proved that enterprise-caliber, cross-platform, managed code for executables is possible. Without the JVM, CIL and CLR would have been a very tough sell in Redmond.

The Software Libraries

Every language comes with a software library, so what is important about the Java and C# libraries? To begin with, they are very large, very comprehensive, and open (in Java's case). Microsoft has yet to decide what it will do about its .NET Base Classes, many of which have been written in C#. In fact, C# already has been used to produce millions of lines of for-production code. Some of these Base Class groupings include APIs for the following:


It is in the software libraries where C# departs most strongly from the Java model. One of Java's strengths is that it makes available on all platforms a huge, open, comprehensive set of routines for all aspects of computing. Even better, over the past five years the library has become more reliable and faster. C#, with its dedication to interoperate with other languages through the .NET Framework and CLR, takes a different approach. It, along with XML SOAP and SCL, is designed to make the huge COM, COM+ and Win32 APIs more available to all languages across all platforms. The direction is right — how reliable and fast it will be is still to be determined.

C# Innovations

C# brings its own unique innovations to the table. There are a number of new C# goodies like:

@"\\Print this\\n!"
verbatim strings which allow newlines, tabs and other whitespace.
 
case EDIT: doEdit(); break;
Strings can be case target in switch statements.
 
stack[ii]=9;
Indexers allow users to create array-like access to their multi-valued classes.
 
goto GoToIsBetter;
the goto is BACK.
 
myProperty.name = "JBS";
like indexers, properties simplify access to a class' private data.
 
public static int x=1, y, z; is equivalent to: public static int x=1; public static int y; public static int z;

Destructors are restored making class instance clean up easier.

Namespace ERPFeatures{ ... }
namespaces allow more precise control of class visibility.
 
#define DEBUGON
preprocessor statements are back with neat behaviors.

This is only a sampling of some distinguishing features in C#. But perhaps the key innovations in C# are geared towards making the language more interoperable. First, primitive types have been unified into the C# object model so that special wrapper classes like Java's Integer for int or Byte for byte do not have to be declared. In addition, the mechanism for creating your own types is open, so interfacing with languages that have unique base types is simplified. Second, by making parameter passing much richer with ref, in, out, and params parameter-passing keywords, interfacing to other APIs, components and languages has been considerably eased. Finally, by adding attributes that allow passing specific info in metadata to the .NET Common Language Runtime, programmers can take advantage of being able to trigger specific runtime behavior depending on the attributes passed through to .NET executables. But this information can be used in any stage of the runtime process — debugging, install, JIT compile, loading and/or execution. In short, C# provides for very powerful interaction with the .NET executables, whatever language was originally used.

Next: Blending Old & New Ideas

1 | 2 | 3 | 4 | 5 | 6

C# Strikes a Chord

C# Strikes a Chord

Blending New and Old Ideas


So what is C#'s genealogy ? Obviously like Java before it, C# borrows key concepts from C++ like inheritance, interfaces, constructors, method signatures and overrides, plus strong declarative typing and public/private/protected modes of data hiding. It also borrows a substantial part of its operator and statement syntax directly from C++. At the same time C# restores and adapts some C++ syntax that Java took away, such as goto, foreach, namespaces, enum, and especially struct with its clever "by-value" innovation. It appears with unsafe and fixed, C# has made pointer arithmetic sufficiently obnoxious that only diehard coders will use it - primarily for performance or interfacing to existing COM and Win32 APIs. C# also restores operator overloading and preprocessor statements while extending this latter concept to in-processing attributes. This means that user defined attribute settings can be passed on to the debugging, profiling, and executable environments.

But C# also borrows much from Java. It has a simple syntax with strong runtime type checking. Single inheritance derived from a master Object is carried to its logical conclusion with primitive types cleverly unified into the object model. C# goes with Java in adopting Unicode and standard bitsizes for primitive type in various hardware implementations. Like Java, C# passes on C++'s template, friend and union syntax and directions. Most important, C# capitalizes on the JVM idea — production of intermediate code that is then compiled and executed in a managed environment that includes memory management, garbage collection, type-safe validations and other user-controlled exception checking. C#, in a key innovation over Java, extends the managed code environment to be parameter-passing rich and primitive-type unified so it can be programming/scripting language neutral (and, if Microsoft so chooses, also platform neutral as well).

    What do you think about C#?  
  Share your views in our forum.  

However, Java has a much more comprehensive, open source API base and some clever deployment options for applets, servlets, beans and Enterprise JavaBeans. It also has a commanding head start — having become the programming language of the Internet on the server side. With wide bandwidth coming available with DSL and cable modems, Java is sure to see a renaissance on the client side with more applets taking advantage of ten times greater download capacity and new Java-robust browsers from Netscape and Opera. Already much project management, OLAP and online learning software use sophisticated Java applets over the yawning security, programming, cross platform compatibility and runtime performance gaps presented by JavaScript and VBScript.

So will C# be just in time to ward off the Java wave? IDC, unlike Microsoft, which severely downplays Java usage, sees the number of Java developers growing at 30 percent per year starting from a 900,000 user base. Sun reports over 2.5 million downloads of the JDK from its site. Regardless of the numbers, C# will be, from a technical viewpoint, a very worthy competitor to Java. Perhaps Javasoft will see fit to steal back some of C#'s innovations, while Microsoft may want to be more open and cross platform with C#. Also Microsoft needs to reduce the six-to-nine months before release of Visual Studio.NET with full IDE development support for C#.

Whither VC++? It is obvious that C# is the driver in the new .NET Framework and executable environment. However, remember what C# and the .Net framework are designed to do — promote interoperability and component reuse. The demos of Cobol, Eiffel, and the host of other "academic" programming languages at C# PDC debut showed just how effective C#, CLR, and .Net Framework can be at making any programming language a first-class player in the .NET Framework. So a lot of languages, including VC++, are going to get a positive shot in the arm from the C# enabled .Net Framework. These languages can now more readily interoperate while providing their own competitive advantage in specific developmental and/or runtime features. In sum, C# derives greatly from both C++ and Java, while adding its own distinctive language innovations. With its any-language interoperability and cross platform potential, C# has the capability to strike a very positive chord in the programming community.

1 | 2 | 3 | 4 | 5 | 6

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.