BBS水木清华站∶精华区

发信人: yyh (一笑了之), 信区: Java        
标  题: C#: A language alternative or just J--?, 
发信站: BBS 水木清华站 (Sat Dec 23 14:57:40 2000) 
 
http://www.javaworld.com/javaworld/jw-12-2000/jw-1221-csharp2_p.html 
C#: A language alternative or just J--?, Part 2 
An in-depth look into the semantic differences and design choices between C# 
 and Java 
Summary 
Despite their enormous similarities, Java and C# differ greatly in many lang 
uage details and also in their basic technical intent. This second article o 
f a two-part series covers C# language constructs and concludes with some sp 
eculation on the idea of standardizing C#. (4,200 words) 
By Mark Johnson 
n Part 1 of this series, I covered the similarities between C# and Java, exp 
lained C#'s role in .Net, speculated on the possible outcomes of using multi 
ple languages in application development, and looked at some high-level diff 
erences between Java and C#. This article covers C# language constructs in d 
epth, points out various language features, and provides short pieces of sam 
ple code that illustrate C# programming principles. It concludes with a rant 
 on C# and the tension between proprietary interests on one hand and open st 
andardization on the other. 
 C#: A language alternative or just J--?: Read the whole series! 
Part 1. What the new language for .Net and post-Java Microsoft means to you 
Part 2. An in-depth look into the semantic differences and design choices be 
tween C# and Java 
C# features 
Some of the differences between C# and Java are simply cosmetic. In particul 
ar, there's the question of capitalization. I don't know for sure, but I'm g 
uessing that the capitalization conventions in C# come from Delphi, as I sus 
pect the WriteLine method also does. The capitalization in C#, with its Main 
() method and string built-in type, feel odd to the Java programmer. Are the 
se conventions simply lifted from Delphi, or are they used rather to make C# 
 look, on the surface, less like Java? If the reason was the latter, I'm afr 
aid it wasn't very successful. The effect is rather like putting lipstick on 
 your dog. He's still your dog, only with lipstick, and he doesn't necessari 
ly look any better or worse for it. 
Fortunately, C# has several features that go beyond the cosmetic. Some of th 
ese, such as enumerated values ("enums"), are simple "syntactic sugar," prov 
iding self-documentation and arguably clearer source code. Other features, s 
uch as delegates and events, are quite useful (though implemented in a confu 
sing way) and provide functionality built into the language that, in Java, r 
equires coding and a nontrivial understanding of Java design patterns. 
This section will cover several interesting C# features. 
Type system 
Several features of the C# type system are interesting. Primitive values can 
 always be treated as objects. There are a few class member types (propertie 
s, structs, enumerations, and delegates) that do not exist in Java. C# array 
s work differently from Java arrays. Operators are overloadable in a fashion 
 similar, but not identical, to that of C++. You can access indexed collecti 
ons through a mechanism called an indexer, which works similarly to an opera 
tor. 
Primitive/object unification 
One feature of the C# type system that is bound to be popular is the use of  
all primitive types as objects. In fact, you can use primitive literal value 
s, such as strings and integers, as if they were objects, without first cons 
tructing a String or Integer object in code, as is necessary in Java. So, fo 
r example, the Java code: 
Integer iobj = new Integer(12); 
System.out.println(iobj.toString()); 
could be expressed in C# more clearly as: 
Console.WriteLine(12.ToString()); 
You'll notice in this example that the literal 12 can be used as an object.  
Since every object in C# is a subclass of class object and every literal val 
ue is an object in its own right, it is always possible to call any method o 
f class object against a primitive variable or primitive literal value. Many 
 Java programmers feel that the distinction between primitive value objects  
and primitive values is an unfortunate one in Java, and the designers of C#  
apparently agree. The processes of automatically converting a primitive valu 
e into an object and vice versa in C# are called boxing and unboxing, respec 
tively. 
Array types 
Array types differ somewhat between C# and Java. Both languages support simp 
le and multidimensional arrays. In both languages, multidimensional arrays c 
an be arrays of arrays, as shown in Table 1. 
Java C# 
int[] arrayOfInt = new 
int[10]; 
 int[] arrayOfInt = new 
int[10]; 
int[][] multiArray = new 
int[10][3]; 
 int[][] multiArray = new int[10][]; 
for (int i = 0; i < 10; i++) { 
   multiArray[i] = new int[3]; 

// Valid in both 
C# and Java 
int[][] multiArray2 = new int[][] { 
   new int []       { 1 }, 
   new int []    { 1, 2, 1 }, 
   new int []   { 1, 3, 3, 1 } 
}; 
 int[][] multiArray2 = new int[3][]; 
multiArray2[0] =     { 1 }; 
multiArray2[1] =  { 1, 2, 1 }; 
multiArray2[2] = { 1, 3, 3, 1 }; 
Table 1. Java and C# array definition and initialization 
Table 1 shows the differences in initialization syntax for Java and C# array 
s. Oddly, Java's initialization syntax is more compact than C#'s, but C# has 
 rectangular arrays that Java lacks. The following example shows the definit 
ion of two rectangular arrays in C#: 
int[,] r2dArray = new int[,] { {1, 2, 3}, {2, 3, 4} }; 
int[,,] r3dArray = { { { 1, 2 }, 
                       { 3, 4 } }, 
                     { { 5, 6 }, 
                       { 7, 8 } } }; 
You'll notice that the second preceding example, r3dArray, uses an acceptabl 
e shorthand (omitting new int [,,]) to initialize the array. The C# specific 
ation states that the element type in the array and the number of dimensions 
 define the array type, but the size of each dimension does not. For example 
, int[4][3][5]and int [3][2][1] are the same type, because they have the sam 
e base type and dimensions. 
Arrays are reference types, meaning they do not copy on assignment. All arra 
ys inherit from the System.Array base class, and therefore inherit all of th 
at class's properties, including the Length property. Since C# arrays are co 
llection types, you can use them with the C# foreach keyword. 
Indexers 
A class's indexer lets you access any instance of that class as if it were a 
n array. A class may define multiple indexers, each of which differs by the  
number and type of its arguments. Indexers are very similar to properties, e 
specially in the syntax for defining them, as shown in the following code ex 
ample: 
public class Sparse2DArray { 
   private double[][] _values; 
   private int _i, _j; 
   public Sparse2DArray(int i, int j) { 
      _i = i; 
      _j = j; 
   } 
   public double this[int i, int j] { 
      set { 
         // Check bounds 
         if (i < 0 || i >= _i || j < 0 || j >= _j) { 
            throw new IndexOutOfRangeException(); 
         } 
         // Create values matrix if it doesn't 
exist 
         if (_values == null) { 
            _values = new double[_i][]; 
         } 
         // Create j'th array if it doesn't exist 
         if (_values[i] == null) { 
            _values[i] = new double[_j]; 
         } 
         _values[i][j] = value; 
      } 
      get { 
          // Check bounds 
         if (i < 0 || i >= _i || j < 0 || j >= _j) { 
            throw new IndexOutOfRangeException(); 
         } 
         // Sparse matrix is zero where there are no 
values 
         if (_values[i] == null || values[i][j] == null) { 
            return 0.0; 
         } else { 
            return _values[i][j]; 
         } 
      } 
   } 
}; 
The indexer is defined with a syntax similar to the definition of a method,  
with the text: public double this[int i, int j]. The set block for the index 
er (everything inside the block within the set { ... }) creates the private  
_values array, or any subarray of that array, as needed to store the value p 
assed to the indexer. The get block (inside get { ... } is the value present 
 at the given [i, j] position, or zero if the value does not exist. You can  
index instances of Sparse2DArray with the square bracket notation used for a 
rrays, like so: 
Sparse2DArray s2d = new Sparse2DArray(1000, 10); 
s2d[512, 6] = 3.14159265; 
Console.WriteLine(s2d[12,5]); // will print zero 
Structs, enumerations, properties, delegates 
C# defines several class member types that do not exist in Java: structs, en 
umerations, properties, delegates. This section describes the function of ea 
ch type. 
Structs 
A struct is somewhat like a struct in C, except that a C# struct may have an 
y kind of class member, including constructors and methods; and the default  
accessibility for struct members is private, rather than public as in C. Lik 
e C structs, though, C# structs always copy by value and are therefore both  
mutable and exempt from dynamic memory management (i.e., garbage collection) 
. Variables that copy by value don't need garbage collection because the mem 
ory used to represent them disappears when those variables go out of scope.  
In many ways, a struct is similar to a class: a struct can implement interfa 
ces and can have the kinds of members that classes can have. But structs can 
't inherit from other structs. 
Interestingly, the scalar types like int and double are implemented in C# as 
 aliases for predefined structs in the System namespace. In other words, whe 
n you define an int variable in C#, for example, you're actually defining an 
 instance of System.Int32, which is a struct predefined in C# language. The  
struct System.Int32, in turn, inherits all of the members of System.Object.  
(While the language specification says structs can't inherit, it also says t 
hey do inherit from System.Object; presumably, this is an exception.) So, ba 
sically, every primitive type in C# is also an object, and therefore "object 
" in C# means something other than the traditional interpretation of "instan 
ce of a class." 
Since primitives, classes, and structs inherit from System.Object, everythin 
g in C# is an object and can be treated as such. This is how C# represents p 
rimitives as objects: they already are objects. Yet instances of primitives  
and structs copy by value, while instances of class copy by reference. Conve 
rsion from value types to reference types and vice versa are the boxing and  
unboxing operations mentioned earlier. 
Enums 
Another class member type Java does not provide is the enum. While similar t 
o enums in C, C# enums are based on an "underlying type," which can be any s 
igned or unsigned integer type. Enumerations are derived from the built-in c 
lass System.Enum, and therefore every enum inherits all of that class's memb 
ers. 
For example, an enum based on an unsigned long integer can be defined as: 
enum description: ulong { 
   Good, 
   Bad, 
   Ugly 
}; 
Enums are inherently type-safe and require explicit type casts when they are 
 assigned to and from integer types, even the type from which the enum is de 
rived. 
A common idiom in Java for "faking" enums is to define public final ints in  
an interface and then inherit the interface, like this: 
public interface Description { 
   public final int Good = 0, 
   public final int Bad = 1, 
   public final int Ugly = 2 
}; 
public class Sheriff: extends Description { 
   protected int _description; 
   public Sheriff() { 
      _description = Good; 
   } 

While this idiom improves readability in Java, it doesn't provide type safet 
y, nor can methods overload on two such "enums," because they're really inte 
gers. C# provides true enumerated types. 
Properties 
Directly accessing the public data members of objects is generally understoo 
d to be poor form. Direct access to a data member of an object inherently br 
eaks data encapsulation and is a maintenance hazard. When a data member is r 
emoved from an existing class, any code that accesses that removed member wi 
ll also need to be fixed. Further, code that accesses a class's public data  
members relies on a particular implementation of that class. The traditional 
 solution to this problem is to provide "accessor methods," or "getters" and 
 "setters," which provide access to information about the object. The value  
set retrieved by an accessor method is typically called a "property." For ex 
ample, a block of text in a word processor might have properties like "foreg 
round color," "background color," and so on. Instead of exposing public Colo 
r members, the object representing a block of text could provide getter and  
setter methods to those properties. This concept of using access methods to  
encapsulate internal virtual object state is a design pattern that spans obj 
ect-oriented languages. It isn't limited to C# or Java. 
C# has taken the concept of properties a step further by actually building a 
ccessor methods into the language semantics. An object property has a type,  
a set method, and a get method. The set and get methods of the property dete 
rmine how the property's value is set and retrieved. For example, a TextBloc 
k class might define its background color property in this way: 
public class TextBlock { 
   // Assume Color is an enum 
   private Color _bgColor; 
   private Color _fgColor; 
   public Color backgroundColor { 
      get { 
         return _bgColor; 
      } 
      set { 
         _bgColor = value; 
      } 
   //... and so on... 
   } 

(Notice in the preceding set block _bgColor is set to value, which is a keyw 
ord that, in this context, means the value of the property.) Some other obje 
ct could set or get a TextBlock's backgroundColor property like this: 
TextBlock tb; 
if (tb.backgroundColor == Color.green) { // 
"get" is called for comparison 
   tb.backgroundColor = Color.red; // "set" is 
called 
} else { 
   tb.backgroundColor = Color.blue; // "set" is 
called 

So, the syntax to access a property looks like a member but is implemented l 
ike a method. Either of the get and set methods is optional, providing a way 
 of creating "read only" and "write only" properties. 
Some would say that Java has properties, since the JavaBeans specification d 
efines properties in terms of method naming conventions and the contents of  
JavaBean PropertyDescriptors. While JavaBeans properties do everything C# pr 
operties do, JavaBeans properties are not built into the Java language, and  
so the syntax for using them is a method call: 
TextBlock tb; 
public class TextBlock { 
   private Color _bgColor; 
   public Color getBackgroundColor() { 
      return _bgColor; 
   } 
   public Color setBackgroundColor(Color value_) { 
      _bgColor = value_; 
   } 
   // ...etc... 

TextBlock tb; 
if (tb.getBackgroundColor() == Color.green) { 
   tb.setBackgroundColor(Color.red); 
} else { 
   tb.setBackgroundColor(Color.blue); 

The meaning of the preceding example code in Java and C# is identical, but t 
he syntax in C# is cleaner. 
You may have heard that property accessors are simply methods used for acces 
sing objects' internal variables. This idea is a complete misunderstanding o 
f what property accessors truly are. While property accessors often, even us 
ually, simply set and return the value of a private variable, property acces 
sors are most useful when they return a calculated or deferred value. What's 
 more, a property accessor that today returns the value of an internal varia 
ble might tomorrow return a value it got from somewhere else, if the class's 
 implementation changed. The classes that access the property don't need to  
know where the property value came from, as they would if they were accessin 
g an internal variable. Property accessors cannot break encapsulation in the 
 way that public field accessors do. They are simply not the same thing. Whe 
ther defined by convention as in Java or built into a language like C#, prop 
erties are an excellent way to improve decoupling between classes. 
Delegates 
Delegates are C#'s answer to C++ function pointers, except that delegates ar 
e safe, and function pointers are dangerous. Both Java and C# have done away 
 with function pointers, finding safer ways to maintain references to behavi 
or that is determined at runtime (which is what function pointers are used f 
or in C++). 
C# borrowed the concept of delegates from Delphi and Visual J++. A delegate  
is a reference to a method, plus either a class or an instance against which 
 the method can be called, depending on whether or not the method is static. 
 Delegates are useful whenever behavior needs to be deferred to another obje 
ct. For example, a sort algorithm might take a delegate as one of its argume 
nts: 
// Declaration of the delegate 
delegate int Comparator(object a, object b); 
class Quicksort { 
   static void sort(Comparator c, object[] objectsToSort) { 
      // ... quicksort logic leading to a 
comparison 
         if (c(objectsToSort[left], objectsToSort[pivot]) > 0) { 
            // recursive call... 
         } else { // ...and so on... 
   } }; 
In the preceding code you see the delegate called Comparator declared and th 
en used as an argument in Quicksort.sort(), which is static. In the "if" sta 
tement, the delegate c is called just as if it were a method. This is equiva 
lent to calling through a function pointer in C, except the delegate is type 
-safe and can't possibly have an illegal value. 
The typical Java approach usually involves implementing an interface, like t 
his: 
public interface Comparator { 
   int compare(Object a, Object b); 

public class Quicksort { 
   public static void sort(Comparator c, Object[] objectsToSort) { 
         // ...quicksort logic... 
         if (c.compare(objectsToSort[left], objectsToSort[pivot]) > 0) { 
         // ... and so on 
      } 
   } 
}; 
The object implementing Comparator in the preceding code will commonly be in 
 an inner or even anonymous class. Again, as in the case of properties, the  
results in Java and C# are quite similar, but the C# syntax is slightly clea 
rer. Delegates are more than just syntactic shorthand for interface calls, h 
owever. A delegate can maintain a reference both to a method and to an insta 
nce upon which that method can be invoked. You'll see an example of this usa 
ge in the next section on events. Also, you'll find a link to a Sun whitepap 
er on delegates in Resources. 
Events and event notification 
C# events operate much like Java 1.1+ events, except that C#'s are integrate 
d into the language. For a class to receive an event, it must have a field o 
r property that is a delegate marked with the event keyword. From inside the 
 class, this delegate member is just like any other delegate: it can be call 
ed, checked to see if it's null, and so forth. From outside the class, howev 
er, there are only two things you can do with it: add or remove a method to  
the delegate, using the operator+= or the operator-=, respectively. Event de 
legates apparently act as collections or lists of references to methods and  
instances. 
In essence, an event delegate is a list of methods to be called when the del 
egate is invoked. In my opinion, this usage is extremely confusing, since in 
 this particular case delegates act like a collection of method pointers, ra 
ther than a single method pointer. The language spec does, however, specify  
that all delegates define addition and subtraction operators, implying that  
any delegate may be used in this way. 
For example, here is the definition of part of a class called MyButton, whic 
h can respond to mouse clicks: 
public delegate void ClickHandler(object source, Event e); 
public class MyButton: Control { 
   public event ClickHandler HandlerList; 
   protected void OnClick(Event e) { 
      if (HandlerList != null) { 
         HandlerList(this, e); 
      } 
   } 
   //... override other methods of Control... 

A dialog class containing one of these buttons could then register itself to 
 receive clicks from the button, adding one of its methods to the button's H 
andlerList with the operator+=, like so: 
public class OneWayDialog: Control { 
   protected MyButton DialPhoneButton; 
   public OneWayDialog() { 
      DialPhoneButton = new MyButton("Dial Phone"); 
      DialPhoneButton.HandlerList += new ClickHandler(DoDial); 
   } 
   public void DoDial(object source, Event e) { 
      // Call method that dials phone number 
   } 

When a OneWayDialog is created, it creates a MyButton and then adds a delega 
te to its method DoDial() to the MyButton's HandlerList. When the user click 
s the MyButton, the framework calls the MyButton's OnClick() method, which t 
hen invokes the HandlerList delegate, resulting in a callback to OneWayDialo 
g.DoDial() against the original OneWayDialog instance. 
In Java, this sort of mechanism (called event multicasting) is handled with  
lists of objects that implement event listener interfaces. Manipulation of t 
hese lists of interfaces must be done manually, although there are "support" 
 classes that do it for you. C# manages these "listener lists" under the hoo 
d by building them into the delegate's semantics. While writing code that ma 
intains listener lists in Java can be a bit tedious, at least it's clear wha 
t's going on. C# "simplifies" the handling of these lists by building it int 
o the language, but at the cost of creating a language feature (the delegate 
) that behaves like a method pointer sometimes and like a collection of meth 
od pointers at other times. This may just be a matter of taste, but personal 
ly I think the delegates' semantics are messy and confusing. On the other ha 
nd, not everyone fully understands Java event listener interfaces the first  
time. 
Operator overloading 
Operator overloading lets you define how operators can be used with their cl 
asses. Operations on instances of those classes can then be expressed in exp 
ression notation using the operators, rather than as explicit method calls.  
Operators used in expressions map directly to the class's operator overloadi 
ng definitions, subject to the language's rules for operator precedence and  
associativity. Mathematics packages often use operator overloading to provid 
e a more intuitive programming model for their objects. For example, instead 
 of matrixA.matMul(matrixB), the operator called operator* can be overloaded 
 to handle matrix multiply, yielding matrixA = matrixA * matrixB;. 
Unlike Java, C# permits operator overloading, using a syntax almost identica 
l to that of C++. Some operators that can be overloaded in C++, such as oper 
ator=, cannot be overloaded in C#. Experienced C++ programmers will have to  
learn and remember the differing rules for C# operator overloading, despite  
the almost identical syntax. 
In light of their experience with C++, Java's designers decided deliberately 
 to leave operator overloading out of Java. The question of operator overloa 
ding in Java is an ongoing debate. Fans of operator overloading claim that l 
eaving it out of the language makes some code unreadable, if not virtually u 
nwritable. Many in the numerics community would like to see operator overloa 
ding added to Java. Overloading detractors say that operator overloading is  
widely abused and that it all too often makes code unmaintainable. For the t 
ime being, the free program JFront (whose name is a pun on CFront) provides  
a preprocessor that implements operator overloading for Java (see Resources) 

Methods 
C# methods have some features that Java does not. In particular, C# provides 
 several modifiers on method parameters and has keywords for virtual methods 
 and method overriding. 
As in C, C# method parameters are value parameters. The ref modifier on a me 
thod parameter makes that parameter a reference, so any change to its values 
 is reflected in the caller's variable. The out modifier indicates that the  
parameter is an output parameter, which is identical to a reference paramete 
r, except that the parameter must be assigned definitely before the method r 
eturns. The params keyword allows variable-length argument lists. For exampl 
e, a method to print an arbitrary number of items might look like this: 
#import main 
void PrintItems(params object[] values) { 
   foreach (object value in values) { 
      Console.WriteLine(value); 
   } 

C# methods are, by default, nonvirtual but can be made virtual by explicit u 
se of the keyword virtual. The C# virtual keyword in a base class defines a  
method as virtual. Subclasses must use the override modifier to override inh 
erited virtual methods. Without the override modifier, a method in a subclas 
s with the same signature as an inherited virtual method simply hides the su 
perclass implementation, although the compiler produces a warning in this ca 
se. The keyword new, used as a method modifier, hides the superclass impleme 
ntation of an inherited virtual method and turns off the error message. 
C#'s designers went to a great deal of trouble to create fine-grained contro 
l over method overriding and hiding, which interacts in various subtle ways  
with accessibility (public, private, internal, and so on). In this case, C#  
is actually more complex than C++. The ref and out method parameter modifier 
s are an old, useful idea, and even more useful in a network environment. Ne 
twork object marshaling code can use them to decide which objects to seriali 
ze and which to ignore. 
Preprocessor 
The C preprocessor was not included in Java because it was seen as an invita 
tion to poor coding practice and an enormous source of bugs. C# includes a p 
reprocessor essentially identical to that of C. Several preprocessors for Ja 
va are freely available for programmers addicted to this feature. 
Native 'unsafe' code 
One of C#'s most widely touted features is its direct integration of native  
code. Code blocks bearing the modifier unsafe can use C#'s pointer types to  
access unmanaged memory and platform-native resources. There is also a fixed 
 keyword, used to "pin" an object to a specific address and protect it from  
the garbage collector. The word unsafe indicates to the compiler that the co 
de being called uses memory pointers. While the C# specification targets per 
formance as the reason for using unsafe code, it will probably be used more  
commonly for accessing the Win32 API and existing DLLs. The Java Native Inte 
rface (JNI) allows access to underlying system resources, but the Java langu 
age itself does not. JNI provides access through a software layer and in ano 
ther language, usually C. 
By this point, you have a good basic understanding of many C# features, whic 
h make it interesting and useful to Windows programmers. But the question re 
mains: Why create this new language? Why not just integrate Java more closel 
y with Windows or, even better, integrate Windows with Java? The next sectio 
n addresses those questions. 
The Standard Open Proprietary architecture 
Microsoft has submitted C# to ECMA (European Computer Manufacturers Associat 
ion), the European standards body that standardized ECMAScript. This is prob 
ably a thumb in the eye to Sun, which scrubbed Java standardization plans wi 
th both ECMA and ISO last year because of copyright concerns. (It remains to 
 be seen how genuinely and successfully Microsoft will push for C# standardi 
zation.) These so-called standardizations of what are essentially proprietar 
y technologies muddy the water for people doing real work in standardization 
 development. True open standards are created in an open forum, with multipl 
e parties providing input as the technology develops. Every high-tech compan 
y would like to be in the position of controlling an open proprietary archit 
ecture. To paraphrase Nixon aide Chuck Colson, if you've got customers by th 
e architecture, their hearts and minds will follow. 
Standards organizations should drive a hard bargain with companies who want  
to develop proprietary technologies behind closed doors and then come beggin 
g for "standardization" long after the time for meaningful community input h 
as passed. Those that fail to do so risk becoming irrelevant repositories fo 
r vested interests instead of advocates for open systems and collaborative d 
evelopment. On the other hand, vendors can hardly be expected to contribute  
heavily to the success of their competitors' infrastructures. Consequently,  
standards organizations should accept proprietary technologies into their pr 
ocesses only if the originators of those technologies are willing to relinqu 
ish veto power over future development. 
Standards are not open simply because their specifications are openly availa 
ble (or, as in the case of ISO, available for a price). True open standards, 
 like XML, are developed openly and collaboratively and often by competing i 
nterests. Those whose designs begin proprietarily become true open standards 
 only when the technology originators have no special place at the table in  
the standards organization. 
For example, Microsoft and Sun are both leaders in the development of XML te 
chnology, yet they will have to compete with everyone else on the basis of t 
echnical excellence, since the standard was developed in full public view. W 
hile other languages such as C and C++ were initially developed behind close 
d doors, the standards process effectively made them common property, in spi 
rit if not in practice. The same cannot be said for Java, since Sun has retr 
acted its bid for standardization. We'll see what ECMA will do about C#. 
Closing remarks 
If I were a Windows developer, I would be rejoicing at the creation of C#. I 
t is much easier to use than C++, and yet is more full featured than Visual  
Basic. MFC programmers, in particular, should flock to this tool. It seems l 
ikely that C# will become a major language for developing under the Windows  
platform. Because of C# creator Anders Hejlsberg's excellent track record, I 
 expect the language to live up to its promises, assuming that Microsoft del 
ivers an implementation that does so. C# solves most of the same problems wi 
th C++ that Java solved five years ago, usually in the same way. C# also sol 
ves the business problems that Microsoft encountered when it found it could  
embrace and extend Java, but not extinguish it. And, if Microsoft marketing  
is to be believed, COM will finally be usable. C# itself is not particularly 
 innovative: there is little in this language that has not been seen before. 
 Still, its skillful combination of these well-understood features will prov 
ide good value to Windows programmers. Of course, those not wanting to limit 
 themselves to Windows can still choose from among the many excellent implem 
entations of Java for Windows. 
Because of its lack of platform neutrality, C# is in no way a "Java killer." 
 Even leaving aside Sun's five-year head start, and Java's successful captur 
e of the "gorilla" (market-owning) position among enterprise server language 
s, C#'s Achilles' heel is that it is tied to Windows. Of course, in theory i 
t isn't. But widespread cross-platform implementation of C# is like widespre 
ad multivendor implementation of Win32 and COM: possible, in theory. 
High-technology consumers today, and especially IT managers, are appropriate 
ly wary of vendor lock-in. Encoding procedural information assets in a way t 
hat ties them to a particular vendor is a Faustian bargain. The Java platfor 
m is neutral with respect to operating systems. If you don't like the servic 
e you are getting from one vendor, or if your needs change, you can find ano 
ther vendor that better meets your requirements. It will be some time before 
 that can be said of C# or .Net. In short, while C# is a fine language for W 
indows programming, it will be able to compete with Java only when C# is fre 
ed from its Windows dependence. For the time being, C# users still won't get 
 to decide where they're going today. 
Acknowledgments 
Many thanks to fellow ITworld.com author Michael Perry, who performed the te 
chnical review for this series, caught several potentially embarrassing mist 
akes for me, and tried his best to rein in my unruly opinions. Be sure to se 
e Perry's article, as well as my discussion with him about C# versus Java, i 
n Resources. 
  About the author 
Mark Johnson is a writer, a consultant, and a JavaBeans columnist and XML gu 
ru at JavaWorld. His interests include design patterns, structured data repr 
esentation, software architecture, enterprise data systems, and codeless sof 
tware development. He is the president of elucify technical communications ( 
etc), a Colorado-based corporation dedicated to clarifying novel or complex  
ideas through clear explanation and example. His client list currently inclu 
des Sun Microsystems, where he is a contract technical writer. 
Home | Mail this Story | Resources and Related Links 
Advertisement: Support JavaWorld, click here! 
(c) Copyright 2000 ITworld.com, Inc., an IDG Communications company 
Resources 
"C#: A language alternative or just J--?, Part 1," Mark Johnson (JavaWorld,  
November 22, 2000): 
http://www.javaworld.com/javaworld/jw-11-2000/jw-1122-csharp1.html 
"C#, The Natural Progression," Michael Perry (JavaWorld, August 2000) -- a h 
igh-level article, reprinted from ITworld.com, that outlines the C# technolo 
gy: 
http://www.javaworld.com/javaworld/jw-08-2000/jw-0804-itw-csharp.html 
ITworld.com and JavaWorld columnists duke it out (pardon the pun) on C# vs.  
Java: 
http://www.javaworld.com/jw-11-2000/jw-1122-letters.html 
Mark Johnson on how Java and C# differ (audio clip 3:45): 
http://mithras.itworld.com/media/hearit/1100/001122mjohnson_csharp.ram 
Mark Johnson compares the pros and cons of .Net and the Java 2 Platform, Ent 
erprise Edition (audio clip 2:18): 
http://mithras.itworld.com/media/hearit/1100/001122mjohnson_msdotnet.ram 
"Bits, Flames, and Links," Bobby Schmidt (MSDN Online, Sept. 29, 2000) -- ge 
ts you started experimenting with C#, and includes a generous resource list: 
 
http://msdn.microsoft.com/library/welcome/dsmsdn/deepc08172000.htm 
"C# under the Microscope" (Slashdot, Aug. 9, 2000) -- a good, quick analysis 
 of C#. The hacker prattle following the article provides more heat than lig 
ht, but also the occasional worthwhile observation: 
http://slashdot.org/articles/00/08/09/1612254.shtml 
"Microsoft .Net vs. J2EE -- How Do They Stack Up?" Jim Farley (java.oreilly. 
com): 
http://java.oreilly.com/news/farley_0800.html 
If you're running Windows 2000, download this "pre-beta" evaluation kit: 
http://msdn.microsoft.com/downloads/default.asp?URL=/code/ 
sample.asp?url=/msdn-files/027/000/976/msdncompositedoc.xml 
"Deep Inside C#: An Interview with Microsoft Chief Architect Anders Hejlsber 
g," John Osborn (www.oreilly.com) -- a fascinating article with the designer 
 of C#. Be sure to read the James Gosling interview mentioned here, since Go 
sling's comments, it appears to me, were used out of context: 
http://windows.oreilly.com/news/hejlsberg_0800.html 
A preliminary injunction in the Sun vs. Microsoft case, from the U.S. Distri 
ct Court in northern California: 
http://techlawjournal.com/courts/sunwvmsft/19981117ord.htm 
"Sharp New Language: C# Offers the Power of C++ and Simplicity of Visual Bas 
ic," Joshua Trupin (MSDN Online, September 2000): 
http://msdn.microsoft.com/msdnmag/issues/0900/csharp/csharp.asp 
"First Impressions of C#: Java Killer or Java Wannabe," David Reilly (EarthW 
eb, Aug. 11,2000): 
http://gamelan.earthweb.com/dlink.resource-jhtml.72.1082.|repository||softwa 
redev|content|article|2000|08|10|SDreillycsharp1|SDreillycsharp1~xml.41.jhtm 
l?cda=true 
"First Impressions of C#: A Language Overview," David Reilly (EarthWeb, Aug. 
 22, 2000): 
http://gamelan.earthweb.com/earthweb/cda/dlink.resource-jhtml.72.1082.|repos 
itory||softwaredev|content|article|2000|08|21|SDreillycsharp2|SDreillycsharp 
2~xml.41.jhtml?cda=true 
"Report from Microsoft PDC 2000," John Ruley (Byte.com, July 17, 2000) -- a  
firsthand report from the Microsoft Professional Developers Conference, wher 
e C# was presented: 
http://www.byte.com/feature/BYT20000714S0003 
"Microsoft Challenges Java with C Sharp," Charles Babcock, (Inter@ctive Week 
, July 3, 2000) -- includes news about potential C# standardization: 
http://www.zdnet.com/intweek/stories/news/0,4164,2597408,00.html 
"Java Business Conference: Sun Cancels Java Standard Plans," John Cox (Netwo 
rk World Fusion, Dec. 8, 1999) -- documents Sun's flip-flop on Java standard 
ization: 
http://www.nwfusion.com/news/1999/1208std.html 
"Microsoft Pitches 'C Sharp' against Java," John Leyden (vnunet.com, June 27 
, 2000): 
http://www.vnunet.com/News/1104875 
"Microsoft Cans Visual J++ Tool," John Geralds (vnunet.com, July 12, 2000) - 
- Surprise, surprise: 
http://www.vnunet.com/News/1106388 
"Microsoft .Net Plans Face Court Hurdle," John Leyden (vnunet.com, June 23,  
2000) -- How will .Net play in the context of the antitrust case? Fear, unce 
rtainty, and doubt, for those who just can't get enough: 
http://www.vnunet.com/News/1104495 
A large list of C# programming articles: 
http://www.hitmill.com/programming/dotNET/csharp.html 
ECMA (European Computer Manufacturers Association) homepage: 
http://www.ecma.ch/ 
ECMA News has a discussion of C#'s submission to ECMA: 
http://www.ecma.ch/ecma1/NEWS/NEWS.HTM#Two%20new%20projects%20for%20ECMA%20T 
C39 
"C Sharp Previews Sound Flat," Charles Babcock, (Inter@ctive Week, July 17,  
2000) has a good competitive analysis: 
http://www.zdnet.com/intweek/stories/news/0,4164,2604273,00.html 
"Microsoft's .Net Strategy," Gopalan Suresh Raj (Oct. 13, 2000): 
http://www.execpc.com/~gopalan/misc/viewpoint.html 
"C# Strikes a Chord," Jacques Surveyer (Dr. Dobb's Journal): 
http://www.ddj.com/articles/2000/0065/0065g/0065g.htm 
"C# Is Pronounced 'See Sharp,'" Arthur Griffith (windows.oreilly.com): 
http://windows.oreilly.com/news/seesharp_0700.html 
JFront, a Java preprocessor that provides operator overloading: 
http://www.winternet.com/~gginc/jfront 
Feedback: jweditors@javaworld.com 
Technical difficulties: webmaster@javaworld.com 
URL: http://www.javaworld.com/jw-12-2000/jw-1221-csharp2.html 
Last modified: Thursday, December 21, 2000  
 
-- 
Life is nothing but conflict and struggle. 
 
 
※ 来源:·BBS 水木清华站 smth.org·[FROM: 162.105.17.22] 

BBS水木清华站∶精华区