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水木清华站∶精华区