Cafe au Lait Special Report: C#

Quote

Viewed through Redmond spectacles, it does make some sense, albeit at the cost of admitting that Real Men Don't Eat Visual Basic. Over the years the VB community has gained more and more O-O features, and in theory at least, a semblance of robustness, but the downside has been that COM projects frequently end in tears when VB is being deployed. Visual Basic in COMland is really just a wrapper for C++ classes - which typically work fine - except synchronisation and tidy error handling really aren't possible. So C# gives Microsoft a grown-up language to throw at developers that has a far shorter learning curve than C++.
--Andrew Orlowski
Read the rest in The Register

Initial Report, Friday June 23, 2000

Cnet's reporting that Microsoft is about to release (or perhaps just announce) its long-awaited Java-Killer, to be named C# (pronounced "C sharp"). This is a C++ derivative with a lot of Java-like features. It will have garbage collection and maybe security. (Not that Microsoft knows the first thing about security; If ActiveX didn't prove that, ILoveYou sure did.) It will probably be Windows only, at least until the FSF gets their hands on it.

The name's cute, but otherwise this strikes me as a yawn. If Microsoft wanted to really challenge Java, they should have gone with Python. I just don't believe it's possible for any major advances in language design to be made while restricting oneself to the mistakes Kernighan and Ritchie made 30 years ago. Many of Java's flaws are the results of needlessly maintaining compatibility with C. Much of Java's simplicity comes from places where it broke with C and C++. (switch statements come immediately to mind.) IMHO, a simpler, easier-to-use language than Java can only come about if you move further away from C and C++, not closer. Discussion on slashdot.

Reader Reports

Date: Wed, 28 Jun 2000 11:59:32 -0700
To: Elliotte Rusty Harold
From: Greg Guerin <glguerin@amug.org>
Subject: flamage-reduced comments on C#

It's difficult to effectively criticize a language spec that's so incomplete. There's really no way to know what's missing because it's not been documented yet, vs. what's missing because it's not a language feature. Of the language features hinted at or mentioned in passing but not described, any critique would be wasted because you'd simply be critiquing YOUR ASSUMPTION of how the feature will behave. I'm actually looking forward to a spec that's good enough to be worth criticizing.

The download of the language reference spec:
http://msdn.microsoft.com/vstudio/nextgen/technology/clangref.exe

leaves plenty out. It starts by being a Windows-specific download (self-extracting ZIP of a Word document). Getting past those format and security hurdles, I made a PDF for future use [[which I can email you if you want (~500KB), but see rant, which you can omit if you post this]].

Despite being posted on the web at a publicly linked URL, the document states that it's an "Unpublished work (c) Microsoft Corp". I suppose this is sort of like those "trade secrets" that get automatically licensed to anyone who can click a button.

There's also this gem:

Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

So I guess I have to get written permission just to download it, eh?

Some of the more obvious things missing:

Despite having more in common with Java than it has differences, C# seems altogether a "looser" language and not as tight or clean as Java. Where Java eschews some feature altogether (pre-processor, 'goto' statement), or provides exactly one way to accomplish something, C# often provides multiple intrinsic language mechanisms. It's not clear to me that this is an advantage, except in marketing bullet-lists.

Wherever possible, it seems that C# has chosen a different key-word than Java:

The C# syntax is also more C++-like than Java is. Where Java (wisely, IMHO) chose to use keywords like extends, C# uses punctuation. C# looks much more like C++ than Java does.

Stylistically, C# seems to like initial-caps on method-names, identical to the style of naming classes:

  class Foo {
    public void SomeMethod()
    { ... }
  }

Personally, I find this needlessly confusing, but I suspect it's a style that will be emulated by hordes of programmers. Blecch!!

C# has a pre-processor. It has:

  #define name

but it's unclear to me if it also has:

  #define name text

or:

  #define name(...) macro(...)

The examples illustrate #define's simply being true/false controls for conditional compilation with the typical #if/#else/#elif/#endif directives.

C# does not seem to have doc-comments, but I can't tell whether it's an undocumented feature or not a language feature at all.

C# has goto and labels, just like C. And you can goto case statements, too.

C# distinguishes the 'struct' type from the 'class' type. The spec says:

Structs differ from classes in several important ways, however: structs are value types rather than reference types, and inheritance is not supported for structs. Struct values are stored either "on the stack" or "in-line".

The apparent difference is that there can't ever be pointers/references to structs, though there can be arrays of them. This is probably faster than class-instances in some cases, but bigger and slower in others.

C# has delegates as full-fledged language constructs. It's sort of like a lightweight version of an 'interface' method (implementation-agnostic as long as method-signature matches). Useful in some cases, I'm sure, but I suspect it will largely be abused as an excuse to avoid having to do better software design.

C# has enums as full-fledged language constructs. These look pretty much like the C/C++ enums, just by glancing at them. Of course, there's the obligatory jab at Java: "The use of enums is superior to the use of integer constants - as is common in languages without enums - because the use of enums makes the code more readable and self-documenting." (Editor's note: and the use of typesafe enums is superior to the use of integer enums, and in fact completely obviates the need for an enum keyword

)

C# has namespaces instead of "packages". Pretty much the same effect, though.

C# has attributes and properties (named attributes) in the language. I'm not sure what these really do for you, other than act as cruft-collectors (IMHO).

C# has events as full-fledged language constructs. It's not clear to me exactly what benefits this provides over simply defining events and handlers using classes or other existing language constructs.

There appears to be support for some kind of versioning (i.e. control over binary compatibility). Unfortunately, the feature is not described in detail, and the example in the language overview is trivial.

C# requires that overrides of super-class methods be declared as such using the key-word override. The C++ keyword virtual is also apparently required, implying to me that virtual method-invocation is NOT the norm. Unfortunately, the distinction is not actually explained anywhere in the doc, so maybe it's vestigial, or maybe it's not.

C# also has a 'foreach' statement that iterates over every element of a collection. Java does the same thing using Enumeration objects. A 'foreach' statement is more convenient, but the concurrency issues are subtle yet nowhere explained. I can see advantages and disadvantages to each scheme, depending on what you need to do, so I don't think there's an unequivocal "winner" for this feature.


Date: Tue, 11 Jul 2000 18:18:45 -0700 From: Greg Guerin <glguerin@amug.org> Subject: a note on C#

In my earlier comments on C#, I noted the absence of a class library (well, the documentation of one). The above URL says:

>The Framework is a common set of classes and libraries that provide the >basis for the .Net building blocks that Microsoft is building to deliver on >its software as a service .Net platform.

Given this mention of "The Framework" and some brief comments in the C# documentation, I strongly suspect that there may not be a distinct "C# class library" as such. Rather, C# will probably use "The Framework" classes, perhaps supplemented by some glue or other run-time support. So the obvious questions now are "What's in The Framework?" and "Where is The Framework specification?"

Conspicuous by its absence was any additional information on a security-model for C# or The Framework.


From: "Larry O'Brien" <lobrien@firstworld.net>
Subject: C# Summary
Date: Wed, 28 Jun 2000 10:18:14 -0700

Ironically for a company that touts "innovation" as its shield against lawsuits, this first-new-language since Visual Basic debuted almost precisely a decade ago shows a remarkable lack of courage. Compared to Apple, whose new Aqua interface is based on the premise that loyalty to the Mac is not about specific widgets but about productivity gains, Microsoft looks precisely like the legacy dinosaurs that it so effectively slew in the middle 80s.

C#, in summary, looks like the product of a two-hour brainstorming session between the creators of Visual Basic, Visual C++, and Turbo Pascal. Aside from minor syntactical issues ("using" vs. "import", ":" vs. "extends"), the major differences in the language appear to be formalization of delegates (callbacks) and attributes, as well as a couple minor things, like structs and enums.

Then there's a huge language change: versioning. They call it that, but actually, it's optional polymorphism. A base class can add a method with the same signature as an existing sub-class method without causing a compilation problem. (class Base ships, class Derived extends it and adds a foo() method. Next version of Base ships and adds a method foo() -- programs using Derived remain compatible.) When a derived class is compiled, it can specify the use of polymorphism:

class Base{
    public void foo(){ System.Console.WriteLine("Base.Foo"); }
    public void bar(){ System.Console.WriteLine("Base.Bar"); }
}
 
class Derived{
    public override void foo(){ System.Console.WriteLine("Derived.Foo"); } 
    public new void bar(){ System.Console.WriteLine("Derived.Bar"); }
 
    static void Main(){
        Derived d = new Derived(); d.foo(); d.bar(); 
        Base b = new Derived(); b.foo(); b.bar();
    }
}

will print "Derived.Foo Derived.Bar Derived.Foo Base.Bar"

While I can see the advantage of versioning for framework writers, I think it is, on balance, quite dangerous when taken in the context of real object-oriented programs. Understanding an inheritance tree is difficult enough; branches that suddenly change dispatching philosophy based on a keyword are going to be prone to error.

Other than versioning, C# contains no readily apparent innovations. The concept of a shared runtime library based on a common object model is a fine one, but hardly proof that Microsoft has the best intentions of the programmers in mind: You will learn the Microsoft-written libraries and then you may use all Microsoft programming languages.

The popularity of programming languages have traditionally followed a 5-7 year cycle, triggered by the early adopters embracing a programming language that addresses the perceived "biggest challenge." We are currently nearing the end of Java's cycle and within two years, mark my words, all the cool kids will be programming something new. It won't be C#.


Date: Fri, 30 Jun 2000 15:46:14 -1000
From: Robin Meade <rmeade@outreach.hawaii.edu>
Subject: C# allows Strings in switch statement

C# allows Strings in switch statement

http://msdn.microsoft.com/library/prelim/csref/vclrfcsharpspec_8_7_2.htm

Actually, I think this is a nice feature that I long wished Java had.

Web (and network) programming is string intensive (processing html form submissions, for example). This feature makes it easier to work with strings.

Compare

String action = request.getParameter("action");
if (action.equals("next")) {
    if (validate(request)) sendNextPage();
    else showErrorMessage();
} else if (action.equals("back")) {
    sendPrevousPage();
} else {
    handleUnkownAction();
}

to

String action = request.getParameter("action");
switch (action) {
  case "next":
    if (validate(request)) sendNextPage();
    else showErrorMessage();
    break;
  case "back":
    sendPrevousPage();
    break;
  case default:
    handleUnkownAction();
}

I think the latter (C# way) is easier to read and understand. Switchability on string values seems to me quite appropriate for a general purpose programming language with a bias towards web and network programming, as Java is.

- Robin Meade


Date: Wed, 28 Jun 2000 14:34:51 -0700
From: Greg Guerin <glguerin@amug.org>
Subject: more flamage-reduced comments on C#

Oops, I forgot to mention that every C# object is automagically a COM object (there's a chapter called "Interoperability" that goes into some detail about this). However, I am sufficiently ignorant of COM that I have no real practical idea of how useful this is, or what the speed/memory costs of it are, or its security implications. It does seem to be something that Windows programmers get excited about, though.

One other thing I've seen in web articles about C# is that it executes on a "virtual processor" (a virtual machine to the rest of the world). However, this is not mentioned at all in the language spec, and I found no further information on it.


Date: Sat, 1 Jul 2000 15:25:08 -0700
From: Greg Guerin <glguerin@amug.org>
Subject: more comments on C#

I found the details on C#'s 'virtual ' keyword. It's pretty much what I expected: you MUST use it on any method which you wish to be overridable. A non-virtual method is resolved at compile-time, using the compile-time type of the object. A virtual method is resolved at run-time, using the run-time type of the object. Like Java, static methods are always non-virtual. Unlike Java, it appears that non-static methods can also be non-virtual, and indeed are by default if not explicitly declared virtual. I see little practical advantage and much needless complexity arising from this feature.

I didn't notice it before, but C# provides operator overloading <sigh>:

The overloadable unary operators are:

+ - ! ~ ++ -- true false

The overloadable binary operators are:

+ - * / % & | ^ << >> == != > < >= <=

Only the operators listed above can be overloaded. In particular, it is not possible to overload member access, method invocation, or the =, &&, ||, ?:, new, typeof, sizeof, and is operators.

All the listed operators can be overloaded and/or defined on class or struct types <groan>. There are also hints that enum's and some other types can have operators defined or overloaded.

I also missed this astonishing "feature" of the 'switch' statement:

Unlike C and C++, execution of a switch section is not permitted to "fall through" to the next switch section... The "no fall through" rule prevents a common class of bugs that occur in C and C++ when break statements are accidentally omitted.

Thus, the following (as it would appear in C) is a C# error:

  switch ( a )
  {
    case 1:
      perform();

    case 2:
      something();

    case 3:
      more();
  }

and requires this structure instead:

  switch ( a )
  {
    case 1:
      perform();
      goto case 2;

    case 2:
      something();
      goto case 3;

    case 3:
      more();
  }

You CAN have multiple labels on the same case-section, so this is legal:

  switch ( a )
  {
    case 1:
    case 2:
      something();
      break;

    case 3:
      otherwise();
  }

If you wish the cases to be mutually exclusive, you use the 'break' statement in The Canonical Way.

As a consolation prize, you can use the string type in switches:

  void dosify( string cmd )
  {
    switch ( cmd.ToLowerCase() )
    {
      case "ls":  doDir();  break;
      case "rm":  doDel();  break;
      case "cp":  doCopy();  break;
      default:  doNothing();  break;
    }
  }

There is no information on how the compiled code performs this, except that the "string equality" operator (equivalent to Java's String.equals() semantics) governs the comparison. So maybe it's a hash-table or maybe it's an if/else chain.

External Links and Reports


If you'd like to add your own comments on this topic, write them up and email them to elharo@metalab.unc.edu. I reserve the right to edit for style and content as well as to select which reports are and are not posted. Generally speaking, the most comprehensive, accurate, and interesting reports will be posted; especially those that introduce new information not already included here. Please be sure to tell me that what you send is intended for publication. By default, I assume that personal email is a private communication and will not republish it unless told otherwise. At the same time, if you specifically wish to remain anonymous, tell me that too. Otherwise I'll assume it's permissible to cite you as the source of a particular piece of information or story. Thanks!

Cafe au Lait Home | Java Books | Java Trade Shows | Java Course Notes | Java FAQ | Java Tutorial | Java User Groups | Java Mailing Lists | Java Questions | Java Quotes

Copyright 2000 Elliotte Rusty Harold
Individual reports copyright by their respective authors.
elharo@metalab.unc.edu
Last Modified July 19, 2000 10:58:45 AM