RE: discussion came up on languages – C++, Java and C#.
The development of OO languages kind of started with C++ (LISP actually…)…then came Java… a high level
OO language that was agnostic… hardware independent… still very much in use.
But then Microsoft got a hold of it and made it proprietary, and in so doing violated the
licensing agreement of Java and lost a lawsuit; they were fined a mere $35Million and restrained
from distributing Java, so they developed C#. It’s interesting to note that you find little or no information
about the lawsuit against Microsoft and the bias/attitude of the Microsoft folks toward Java. To
hear the Microsoft types tell it, they created C# out of nothing all on their own.
My advice to developers and students has been to learn C, C++ and Java, focusing on
Java as it is highly recognized, non-denominational and portable. Once one knows Java
the other two (C++ and C#) are relatively easy to pickup. If one knows C#, learning the differences
to get to Java will further enhance their ability to support multiple projects and therefore
have greater job security and marketability. Skill sets are important. Limiting oneself to
one flavor of anything is a CLM and could drastically limit your future, as well as your career.
If one is going to limit themselves, best to limit to the industry standard and not the current industry
leader. It should also be noted that in the area of systems administration a non-microsoft admin
will make anywhere from 30 to 60% more, and also manage more systems, and support the Microsoft
systems at the same time. If you’re in IT, it’s about providing a workable solution to the enterprise that
protects data and operations. One size does not typically fit all.
In today’s automated HR processes if one doesn’t have the correct acronym listed you don’t get selected. Taking
the time to learn the industry standard first, and then the proprietary will ensure employment. If I had
to pick one to master it would be Java, it is widely used in web and databases and I could see my way
through to learn C++ and C# having a paying reference point.
Found some websites that provide a summary of the differences:
http://www.harding.edu/fmccown/java_csharp_comparison.html
This is a quick reference guide to highlight some key syntactical differences between Java and C#.
This is not a complete overview of either language. Hope you find this useful!
Also see VB.NET and C# Comparison.
EXAMPLES OF CODE ON THIS PAGE – Java / C# - excellent…
http://www.25hoursaday.com/CsharpVsJava.html
There are a large number of syntactic similarities between Java and C#, similarly almost every Java keyword has a C# equivalent except for a few like transient, throws and strictfp. Below is a table of Java and C# keywords with the Java keywords in red while the equivalent C# keywords are in blue.
C# keyword | Java keyword | C# keyword | Java keyword | C# keyword | Java keyword | C# keyword | Java keyword |
abstract | abstract | extern | native | operator | N/A | throw | throw |
as | N/A | false | false | out | N/A | true | true |
base | super | finally | finally | override | N/A | try | try |
bool | boolean | fixed | N/A | params | .... | typeof | N/A |
break | break | float | float | partial | N/A | uint | N/A |
byte | N/A | for | for | private | private | ulong | N/A |
case | case | foreach | for | protected | N/A | unchecked | N/A |
catch | catch | get | N/A | public | public | unsafe | N/A |
char | char | goto | goto1 | readonly | N/A | ushort | N/A |
checked | N/A | if | if | ref | N/A | using | import |
class | class | implicit | N/A | return | return | value | N/A |
const | const1 | in | N/A | sbyte | byte | virtual | N/A |
continue | continue | int | int | sealed | final | void | void |
decimal | N/A | interface | interface | set | N/A | volatile | volatile |
default | default | internal | protected | short | short | where | extends |
delegate | N/A | is | instanceof | sizeof | N/A | while | while |
do | do | lock | synchronized | stackalloc | N/A | yield | N/A |
double | double | long | long | static | static | : | extends |
else | else | namespace | package | string | N/A | : | implements |
enum | N/A | new | new | struct | N/A | N/A | strictfp |
event | N/A | null | null | switch | switch | N/A | throws |
explicit | N/A | object | N/A | this | this | N/A | transient2 |
NOTE: Although goto
and const
are Java language keywords they are unused in the Java language.
NOTE: The [NonSerialized]
attribute in C# is equivalent to the transient
keyword in Java.
http://rayli.net/blog/2008/04/top-10-differences-between-java-and-c/
My latest transition from Java to C# left me scratching my head and scrambling to find the differences. Don’t get me wrong — they are very similar, but some key syntax and philosophical differences set these two languages apart. Below are my top 10 differences that I wish someone told me before I pulled out yet more hair.
Gotcha #10 – Give me my standard output!
Gotcha #9 – Namespaces == Freedom
Gotcha #8 – What happened to super?
Gotcha #7 – Chaining constructors to a base constructor
Gotcha #6 – Dagnabit, how do I inherit?
Gotcha #5 – Why don’t constants remain constant?
Gotcha #4 – Where is ArrayList, Vector or Hashtable?
Gotcha #3 – Of Accessors and Mutators (Getters and Setters)
Gotcha #2 – I can’t override!?
And the #1 gotcha…
http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java
Java | C# | |
Single-root (unified) type system | No | Yes |
Yes; 8, 16, 32, 64 bits | Yes; 8, 16, 32, 64 bits | |
No[1] | Yes; 8, 16, 32, 64 bits | |
Yes | Yes | |
Date/time | Yes; reference type | Yes; value type |
IEEE 754 binary32 floating point number | Yes | Yes |
IEEE 754 binary64 floating point number | Yes | Yes |
High precision floating point number | No; but see Arbitrary size decimals | 128-bit (28 digits) Decimal type |
Yes | Yes | |
Immutable reference type, Unicode | Immutable reference type, Unicode | |
Reference type; no operators | Yes | |
Reference type; no operators | No | |
No | Yes | |
Yes | Yes | |
Yes | Yes | |
No; only primitive types | Yes | |
Yes; reference type | Yes; scalar | |
No; but wrapper types | Yes | |
No | Yes | |
No | Yes |
Reference types | Java | C# |
Yes | Yes | |
Yes | Yes | |
Yes | No | |
Yes; proxy generation | Yes; object contexts |
Object orientation | Java | C# |
Yes | Yes | |
Yes | Yes | |
Yes | Yes | |
Member accessibility levels | Public, package, protected, private | Public, internal, protected, private |
Class level inner classes | Yes | Yes |
Instance level inner classes | Yes | No |
No | Yes | |
Statement level anonymous classes | Yes | No |
Implicit (inferred) anonymous classes | No | Yes |
Deprecation/obsolescence | Yes | Yes |
Overload versioning | Some | Yes |
No, but see JavaBeans spec | Yes | |
No; but the base class library does feature an event mechanism | Yes | |
No | Yes | |
Indexers | No | Yes |
Implicit conversions | No | Yes |
Explicit conversions | No | Yes |
Fields and initialization | Java | C# |
Yes | Yes | |
Yes | Yes | |
Static (class) constructors | Yes | Yes |
Instance constructors | Yes | Yes |
Yes | Yes | |
Instance initializers | Yes | No |
Object initialization | Bottom-up (fields and constructors) | Top-down (fields); bottom-up (constructors) |
Object initializers | No | Yes |
Collection initializers | No; can be modelled | Yes |
Array initializers | Yes | Yes |
Methods and properties | Java | C# |
Static imports | Yes | No |
Virtual | Virtual by default | Non-virtual by default |
Yes | Yes | |
Sealing | Yes | Yes |
Explicit interface implementation | No | Yes |
Value (input) parameters | Yes | Yes |
Reference (input/output) parameters | No | Yes |
Output (output) parameters | No | Yes |
Yes | Yes | |
Optional arguments | No | Yes |
Named arguments | No | Yes |
No | Yes | |
Extension methods | No | Yes |
Conditional methods | No | Yes |
Partial methods | No | Yes |
Generics | Java | C# |
No | Yes | |
Runtime realization | No | Yes |
Yes | Yes | |
Yes | Yes | |
Reference type constraint | Yes; implicit | Yes |
Value/primitive type constraint | No | Yes |
Constructor constraint | No | Yes |
Relation constraint | Yes | Yes |
Primitive/value type support | No | Yes |
Migration compatibility | Yes | No |
Java | C# | |
Method references | No; some use cases covered by anonymous inner classes | Yes |
No; some use cases covered by anonymous inner classes | Yes | |
No | Yes | |
Generic query language | No | Yes |
Java | C# | |
Late-bound (dynamic) type | No | Yes |
Java | C# | |
Runtime type information | Yes; but with type erasure | Yes |
Runtime generics realization | No | Yes |
Runtime type construction | No; third party tools exist | Yes |
Statements | Java | C# |
Yes | Yes | |
Yes | Yes | |
Flow control | Yes | Yes |
Yes | Yes | |
Exception control | Yes | Yes |
Variable declaration | Yes | Yes |
Variable type inference | No | Yes |
Deterministic disposal (ARM-blocks) | No | Yes |
Expressions and operators | Java | C# |
Arithmetic operators | Yes | Yes |
Logical operators | Yes | Yes |
Bitwise logic operators | Yes | Yes |
Conditional | Yes | Yes |
String concatenation | Yes | Yes |
Casts | Yes | Yes |
Yes; implicit | Yes; implicit | |
Yes; implicit | Yes; explicit | |
Lifted operators | No | Yes |
Overflow control | No | Yes |
Strict floating point evaluation | Yes; opt-in/out | No |
Verbatim (here-)strings | No | Yes |
Exceptions | Java | C# |
Checked exceptions | Yes | No |
Try-catch-finally | Yes | Yes |
Arrays and Collections | Java | C# |
Yes | Partial | |
One-dimensional, zero-based index arrays | Yes | Yes |
Rectangular (multidimensional) arrays | No | Yes |
Jagged (arrays of arrays) arrays | Yes | Yes |
Non-zero based arrays | No | Some |
Unified arrays and collections | No | Yes |
Yes | Yes | |
Sorted dictionaries | Yes | Yes[2] |
Sets | Yes | Yes |
Sorted sets | Yes | Yes[3] |
Lists/vectors | Yes | Yes |
Yes | Yes | |
Yes | No | |
Bags/multisets | Yes | Yes |
Java | C# | |
Metadata annotations/attributes | Interface based | Class based |
Positional arguments | No; unless a single argument | Yes |
Named arguments | Yes | Yes |
Default values | At definition | Through initialization |
Nested types | Yes | Yes |
Specialization | No | Yes |
Conditional metadata | No | Yes |
Java | C# | |
Packages | Namespaces | |
Packaging | Package | Assembly |
Classes/assembly search path | Yes; ClassPath | No; /lib |
File contents | Restricted | Free |
Conditional compilation | No | Yes |
Custom errors/warnings | No | Yes |
Explicit regions | No | Yes |
Java | C# | |
Threads | Yes | Yes |
Yes | Yes | |
Task based parallelism | No[4] | Yes[5] |
Yes | Yes | |
Yes | Yes | |
Thread local variables | Yes | Yes; ThreadStaticAttribute |
Native interoperability | Java | C# |
External/native methods | Yes | Yes |
Marshalling | External glue code required | Yes; metadata controlled |
Pointers and arithmetics | No | Yes |
Native types | No | Yes |
Fixed size buffers | No | Yes |
Explicit stack allocation | No | Yes |
Address-of | No | Yes |
No | Yes |
Platform support | Java | C# |
Yes | Yes | |
Yes | Yes | |
Yes | Yes | |
Yes | Partial | |
Yes | Partial? | |
Yes[6] | Yes | |
Yes | Yes | |
Yes | Yes[7] |
http://www.codeproject.com/KB/cs/Java_and_C.aspx
By Ghulam Murtaza | 11 Jan 2008
C# includes more primitive types and the functionality to catch arithmetic exceptions.
Includes a large number of notational conveniences over Java, many of which, such as operator overloading and user-defined casts, are already familiar to the large community of C++ programmers.
Event handling is a "first class citizen"—it is part of the language itself.
Allows the definition of "structs", which are similar to classes but may be allocated on the stack (unlike instances of classes in C# and Java).
C# implements properties as part of the language syntax.
C# allows switch statements to operate on strings.
C# allows anonymous methods providing closure functionality.
C# allows iterator that employs co-routines via a functional-style yield
keyword.
C# has support for output parameters, aiding in the return of multiple values, a feature shared by C++ and SQL.
C# has the ability to alias namespaces.
C# has "Explicit Member Implementation" which allows a class to specifically implement methods of an interface, separate from its own class methods. This allows it also to implement two different interfaces which happen to have a method of the same name. The methods of an interface do not need to be public; they can be made to be accessible only via that interface.
C# provides integration with COM.
Following the example of C and C++, C# allows call by reference for primitive and reference types.
Java's strictfp
keyword guarantees that the result of floating point operations remain the same across platforms.
Java supports checked exceptions for better enforcement of error trapping and handling.
There are no unsigned primitive numeric types in Java. While it is universally agreed that mixing signed and unsigned variables in code is bad, Java's lack of support for unsigned numeric types makes it somewhat unsuited for low-level programming.
C# does not include checked exceptions. Some would argue that checked exceptions are very helpful for good programming practice. Others, including Anders Hejlsberg, chief C# language architect, argue that they were to some extent an experiment in Java and that they haven't been shown to be worthwhile [1] [2].
C#'s namespaces are more similar to those in C++. Unlike Java, the namespace does not specify the location of the source file. (Actually, it's not strictly necessary for a Java source file location to mirror its package directory structure.)
C# includes delegates, whereas Java does not. Some argue that delegates complicate the method invocation model, because they are handled through reflection, which is generally slow. On the other hand, they can simplify the code by removing the need to declare new (possibly anonymous) classes to hook to events.
Java requires that a source file name must match the only public class inside it, while C# allows multiple public
classes in the same file.
C# allows the use of pointers, which some language designers consider to be unsafe, but certain language features try to ensure this functionality is not misused accidentally. Pointers also greatly complicate technologies such as Java's RMI (Remote Method Invocation), where program objects resident on one computer can be referenced within a program running on an entirely separate computer. Some have speculated that the lack of memory pointers in Java (substituted by the more abstract notion of object references) was a nod towards the coming of grid computing, where a single application may be distributed across many physical pieces of hardware.
C# supports the goto
keyword. This can occasionally be useful, but the use of a more structured method of control flow is usually recommended.
C# has true multi-dimensional arrays, as well as the array-of-arrays that is available to Java (which C# calls jagged arrays). Multi-dimensional arrays are always rectangular (in the 2D case, or analogous for more dimensions), whereas an array-of-arrays may store rows (again in the 2D case) of various lengths. Rectangular arrays may speed access if memory is a bottleneck (there is only one memory reference instead of two; this benefit is very dependent on cache behavior) while jagged arrays save memory if it's not full but cost (at the penalty of one pointer per row) if it is. Rectangular arrays also obviate the need to allocate memory for each row explicitly.
Java does not include operator overloading, because abuse of operator overloading can lead to code that is harder to understand and debug. C# allows operator overloading, which, when used carefully, can make code terser and more readable. Java's lack of overloading makes it somewhat unsuited for certain mathematical programs. Conversely, .NET's numeric types do not share a common interface or superclass with add/subtract/etc. methods, restricting the flexibility of numerical libraries.
Methods in C# are non-virtual by default. In Java however, methods are virtual by default. Virtual methods guarantee that the most overridden method of an object will be called which is determined by the runtime. You always have to keep that in mind when calling or writing any virtual method! If the method is declared as non-virtual, the method to invoke will be determined by the compiler. This is a major difference of philosophy between the designers of the Java and .NET platforms.
Java 1.5's generics use type-erasure. Information about the generic types is lost when Java source is compiled to bytecode. .NET 2.0's generics are preserved after compilation due to generics support starting in version 2.0 of the .NET Common Language Runtime, or CLR for short. Java's approach allows Java 1.5 binaries to be run in the 1.4 JRE, at the cost of additional runtime typechecks.
C# is defined by ECMA and ISO standards, whereas Java is proprietary, though largely controlled through an open community process.
The C# API is completely controlled by Microsoft, whereas the Java API is managed through an open community process.
The .NET run-time allows both managed and unmanaged code, enabling certain classes of bugs that do not exist in Java's pure managed code environment but also allows interfacing with existing code.
http://askville.##FIX##/difference-C%23-Java/AnswerViewer.do?requestId=8374427
They are both high-level object-oriented programming languages with somewhat similar syntax.
Java (as originally implemented by Sun) is cross-platform language that relies on its own system foundation called "Java virtual machine". A Java program is usually complied into an intermediate code (called "byte code"), which can theoretically be executed on any computer with any operating system, as long as a standards-compliant Java virtual machine exists on that computer. The function of the Java virtual machine is to translate the byte code into executable code native for the operating system on which the computer runs.
C# is a Windows-specific language that relies on Windows system foundation (more specifically, on the .Net framework). Programs written in C# generally can run only on Windows (although it is sometimes possible to make them cross-platform). Depending on the nature of the program, it can be compiled into a Windows executable or into Microsoft Intermediate Language (MSIL), which is used by .Net to couple pieces of code originally written in different languages.
Both languages can be used for Web development; you can write Java Server Pages (JSP) in Java or
.Net Active Server Pages (ASP.Net) in C#...
a few more sites:
http://msdn.microsoft.com/en-us/library/ms836794.aspx
http://stackoverflow.com/questions/295224/what-are-major-differences-between-c-and-java
http://backtothecode.blogspot.com/2010/04/similarities-and-differences-between.html
http://en.csharp-online.net/CSharp_Compared%E2%80%94Differences_Between_CSharp_and_Java
http://www.kuro5hin.org/story/2002/6/25/122237/078
http://www.cs.columbia.edu/~eaddy/publications/csharpvsjava-eaddy-ddj-feb01.pdf
http://www.c-sharpcorner.com/UploadFile/ghulam_murtaza7/C01112008164858PM/C.aspx
by Budi Kurniawan
06/07/2001
C# (C-Sharp) is Microsoft's new programming language, promoted as "the first component-oriented language in the C/C++ family." Despite the claim, however, many people think that C# is rather a clone of, or Microsoft's replacement for, Java. Is it true?
This article shows the evidence that C# is more than a sibling of Java. If you are a Java programmer who wants to learn or know more about C#, reading this article is the first ten minutes you should invest in.
Given the current hype, it is always interesting to compare C#, whose specification was written by Microsoft's Anders Hejlsberg and Scott Wiltamuth, with both C++ and Java. Considering the tone of recent IT newspapers' headlines, it is not too surprising if you already know that C# is closer to Java than to C++. For those who just joined the discussion, Table 1 below lets you see for yourself. Conclusion: Java and C# are not Siamese twins, but C#'s most important features are closer to Java than to C++.
Table 1: C#'s most important features compared with those of C++ and Java
Feature | C# | C++ | Java |
Inheritance | Single class inheritance, multiple interface implementation | Multiple class inheritance | Single class inheritance, multiple interface implementation |
The notion of interface | Through the "interface" keyword | Through abstract class | Through the "interface" keyword |
Memory management | Managed, using a garbage collector | Manual | Managed, using a garbage collector |
Pointers | Yes, but only in the rarely-used unsafe mode. References are used, instead. | Yes, a very commonly used feature. | Not at all. References are used, instead. |
Form of Compiled Source Code | .NET intermediate language (IL) | Executables. | Byte code. |
One common base class | Yes | No | Yes |
After these outlined important features, read on to find out some important differences between C# and Java.
Primitives in C# are called value types and there are more predefined value types than in Java. For example, C# has uint
, or unsigned integer. Table 2 lists all the predefined types in C#.
Table 2: Value types in C#
Type | Description |
| The ultimate base type of all other types |
| String type; a string is a sequence of Unicode characters |
| 8-bit signed integral type |
| 16-bit signed integral type |
| 32-bit signed integral type |
| 64-bit signed integral type |
| 8-bit unsigned integral type |
| 16-bit unsigned integral type |
| 32-bit unsigned integral type |
| 64-bit unsigned integral type |
| Single-precision floating point type |
| Double-precision floating point type |
| Boolean type; a |
| Character type; a |
| Precise decimal type with 28 significant digits |
Forget the static final
modifiers in Java. In C# constants can be declared using the const
keyword.
public const int x = 55;
In addition, the designers of C# added the readonly
keyword, which you can use if the constant value cannot be determined at compile time. These read-only fields can only be set through an initializer or a class constructor.
In Java, the entry point of a public class is the public static method named main
, which accepts an array of String objects as arguments and returns no value. In C#, the main method is the public static method called Main
(with capital M), which also accepts an array of String objects and returns no value, as given in the following signature.
public static void Main(String[] args)
However, there is more. If you are not passing anything to the Main
method, you can use an overload of Main
, the one without an argument list. Therefore, the following Main
method is also a valid entry point.
public static void Main()
Furthermore, the Main
method can also return an int, if you want. For example, the Main
method of the following code returns 1.
using System;
public class Hello {
public static int Main() {
Console.WriteLine("Done");
return 1;
}
}
As a comparison, overloading the main method is illegal in Java.
Unlike in Java, where the switch
statement can only be used on integers, in C# switch
can also work with string variables. Consider the following C# code that uses the switch statement with a string variable.
using System;
public class Hello {
public static void Main(String[] args) {
switch (args[0]) {
case "boss":
Console.WriteLine("Good morning, Sir. We are ready to serve you.");
break;
case "employee":
Console.WriteLine("Good morning. You can start working now.");
break;
default:
Console.WriteLine("Good morning. How are you today?");
break;
}
}
}
Unlike in Java, the switch statement in C# does not allow fall-through when reading code by requiring that each case
block have either a break at the end of the block or a goto
another case
label in the switch.
A foreach
statement enumerates the elements of a collection, executing a statement for each element of the collection. Consider the following code.
using System;
public class Hello {
public static void Main(String[] args) {
foreach (String arg in args)
Console.WriteLine(arg);
}
}
If you pass arguments when calling the executable, such as the following
Hello Peter Kevin Richard
The output will be the following lines of text.
Peter
Kevin
Richard
In C#, there exist unsigned variable types such as uint
and ulong
. Therefore, in C# the right shift operator (>>
) works differently on unsigned variable types and signed variables (such as int
and long
). Right shifting uint
or ulong
discards the low-order bits and sets high-order empty bit positions to zero. With int
and long
variables, however, the >>
operator discards the low-order bits and set the high-order empty bit positions to zero only if the variable value is positive. For operations on a negative number, the high-order empty bit positions are set to 1.
In Java, there is no unsigned variable. Therefore, you use the >>>
operator to include negative bits in right shifting, and use the >>
operator otherwise.
In Java, goto
is a keyword that is not used. In C# goto brings you to the specified label. However, C# treats goto
with extra care. For instance, a goto
cannot be used to jump into a statement block. In Java, you use labeled statements with break
or continue
to replace goto
in C#.
Declaring an array in Java is very flexible. Indeed, there are a number of forms that are all legal. For example, the following lines of code are equivalent.
int[] x = { 0, 1, 2, 3 };
int x[] = { 0, 1, 2, 3 };
However, in C# only the first line is valid. The [] cannot be placed after the variable name.
A package in C# is called a namespace. To import a namespace in C# you use the word "using." The following code imports the System namespace for use.
using System;
However, unlike in Java, C# allows the use of an alias for a namespace or a class in a namespace.
using TheConsole = System.Console;
public class Hello {
public static void Main() {
TheConsole.WriteLine("Using an alias");
}
}
Conceptually, Java packages are the same as .NET namespaces. However, implementations are different. In Java, package names are also a physical thing that determines the directory structure where your .java
files must reside. In C#, there is a complete separation between physical packaging and logical naming, so the name for your namespace has nothing to do with the physical packaging. In C#, each source file can contribute to multiple namespaces and can take multiple public classes.
The physical packaging in .NET is called assembly. Each assembly contains a manifest that enumerates the files that are contained in the assembly, controls what types and resources are exposed outside the assembly, and maps references from those types and resources to the files that contain the types and resources. Assemblies are self-contained and an assembly can be contained in a single file or be split among a number of files. This packaging mechanism solves the problem with DLL files, notoriously known as DLL Hell.
In Java, the java.lang
package is the default package that is automatically included without having to be imported. To output a piece of text to the console, you can write the following code.
System.out.println("Hello world from Java");
In C#, there is no default package. To output text to the console, you use the WriteLine method of the Console object in the System namespace. However, you must always import the package explicitly. Thus, the following code.
using System;
public class Hello {
public static void Main() {
Console.WriteLine("Hello world from C#");
}
}
Java and C# are both fully object-oriented languages. In terms of the three principles of object-oriented programming, they could not be more similar.
Each member of a class has a form of accessibility. The access modifiers in C# are comparable to those in Java, with the addition of internal
. In short, there are five forms of accessibility in C#, as given below.
public
members are available to all code.protected
members are accessible only from derived classes.internal
members are accessible only from within the same assembly.protected internal
members are accessible only from derived classes within the same assembly..private
members are accessible only from the class itself.You use the keyword "extends" when performing inheritance in Java. C# adopts the C++ style when extending a class. For instance, the following code is how you create a new class named Button
by extending a parent class called Control
.
public class Button: Control {
.
.
.
}
Since there is no final
keyword in C#, if you do not want your class to be extended, you can use the sealed
keyword, like in the following example.
sealed class FinalClass {
.
.
.
}
The notion of interface in C# is very much like that in Java. There is the keyword interface
and an interface can extend one or more other interfaces. By convention, an interface name starts with the capital I. The following code is an example of an interface in C#, which is indistinguishable from an interface in Java.
interface IShape {
void Draw();
}
The syntax for extending an interface is the same as extending a class. For example, the IRectangularShape
interface below extends the IShape
interface.
interface IRectangularShape: IShape {
int GetWidth();
}
If you are extending from two or more interfaces, the list of parent interfaces are separated by commas, like in the following code.
interface INewInterface: IParent1, IParent2 {
}
Unlike Java, however, an interface in C# must not contain fields.
Note also that in C#, all methods in an interface are public by default. Unlike Java, where the modifier public
could be present in a method signature (even though this is not necessary), explicitly specifying an interface method as public is illegal in C#. For example, the following interface will generate a compile error in C#.
interface IShape {
public void Draw();
}
The is
operator in C# is the same as the instanceof
operator in Java. Both can be used to test whether or not an instance of an object is of a particular type. The as
operator in C# has no equivalent in Java. It is very similar to the is
operator, but it is more aggressive in that it also tries to convert the tested object reference into the type in question, if the type is correct. If not, the variable reference will be set to null.
To really understand how as
operates, consider the use of is
in the following code, where there is an interface called IShape
and two classes (Rectangle
and Circle
) that both implement IShape
.
using System;
interface IShape {
void draw();
}
public class Rectangle: IShape {
public void draw() {
}
public int GetWidth() {
return 6;
}
}
public class Circle: IShape {
public void draw() {
}
public int GetRadius() {
return 5;
}
}
public class LetsDraw {
public static void Main(String[] args) {
IShape shape = null;
if (args[0] == "rectangle") {
shape = new Rectangle();
}
else if (args[0] == "circle") {
shape = new Circle();
}
if (shape is Rectangle) {
Rectangle rectangle = (Rectangle) shape;
Console.WriteLine("Width : " + rectangle.GetWidth());
}
if (shape is Circle) {
Circle circle = (Circle) shape;
Console.WriteLine("Radius : " + circle.GetRadius());
}
}
}
After the code is compiled, the user can enter either "rectangle" or "circle" as a shape in args[0]
of the Main
method. If "circle" is entered, shape
is then instantiated to a Circle
object. On the other hand, if the user types in "rectangle," shape
is instantiated to a Rectangle
. The shape is then tested for its object type using the is
operator. If it is a rectangle, then shape
is cast to a Rectangle
object and its GetWidth
method is called. If it is a circle, shape
is cast to a Circle
object and its GetRadius
method is called.
Using the as
operator, the example code above can be modified as in the following.
using System;
interface IShape {
void draw();
}
public class Rectangle: IShape {
public void draw() {
}
public int GetWidth() {
return 6;
}
}
public class Circle: IShape {
public void draw() {
}
public int GetRadius() {
return 5;
}
}
public class LetsDraw {
public static void Main(String[] args) {
IShape shape = null;
if (args[0] == "rectangle") {
shape = new Rectangle();
}
else if (args[0] == "circle") {
shape = new Circle();
}
Rectangle rectangle = shape as Rectangle;
if (rectangle != null) {
Console.WriteLine("Width : " + rectangle.GetWidth());
}
else {
Circle circle = shape as Circle;
if (circle != null)
Console.WriteLine("Radius : " + circle.GetRadius());
}
}
}
In the bold lines in the code above, as
is used to convert shape
to Rectangle
without first testing its object type. If shape
is indeed a Rectangle
, shape
is cast into rectangle
as a Rectangle
object and its GetWidth
method is called. If the conversion fails, a second attempt is performed. This time, shape
is cast into circle
as a Circle
object. If shape
is really a Circle
object, circle
will now reference to the Circle
object and its GetRadius
method is invoked.
C# does not have its own class libraries. However, it shares the .NET class libraries that can be used in other .NET languages such as VB.NET or JScript.NET. Something worth noting is the StringBuilder class, which complements the String class. The StringBuilder class is very similar to Java's StringBuffer.
C++ has taught us how inefficient and time-consuming it is to deal with memory management manually. When you create an object in C++, you have to destroy it manually. As code becomes more complex, this task becomes increasingly difficult. Java solved this problem using the garbage collection method that collects unused objects and releases the memory. C# follows suit; however, this is a very natural path to take if you are developing a new OOP language.. C# still preserves the C++ way of managing memory manually when speed is in extreme need, something which is taboo in Java.
You would not be surprised to find out that C# uses an error handling mechanism similar to Java's, would you? In C# all exceptions are derived from the class named Exception. (Aha, why does this sound familiar?) And, yes, you have the familiar try
and catch
statement like in Java. This Exception class is part of the .NET System namespace.
Born after Java was already mature, it is no surprise that C# has some nice features that Java does not have (yet).
An enumerator is a set of related constants. To be exact, an enum type declaration defines a type name for a related group of symbolic constants. For example, you can create an enumerator called Fruit and use it as the value type of a variable to limit the possible values of the variable to those specified in the enumerator.
public class Demo {
public enum Fruit {
Apple, Banana, Cherry, Durian
}
public void Process(Fruit fruit) {
switch (fruit) {
case Fruit.Apple:
...
break;
case Fruit.Banana:
....
break;
case Fruit.Cherry:
...
break;
case Fruit.Durian:
...
break;
}
}
}
In the Process method of the example above, surely you can use an int as the value type of the myVar variable. However, using the enum Fruit limits the possible values to Apple, Banana, Cherry or Durian. Compared to int
, enum is more readable and self-documenting.
A struct is very similar to a class. However, while a class is created in the heap as a reference type, a struct is a value type that is stored on the stack or in-line. Therefore, used with care, structs are faster than classes. A struct can implement interfaces and have the same kinds of members as a class, but a struct does not support inheritance.
However, simply replacing a class with a struct can be disastrous. Because a struct is passed by value, a "fat" struct is slower to pass around because values must be copied to a new place. In the case of a class, only the reference to the class is passed around.
The following is an example of a struct. Note how similar it is with a class. Substituting the word "class" for "struct" gives you a class.
struct Point {
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
In addition to fields, a C# class can also have properties. A property is a named attribute associated with an object or a class. Properties are a natural extension of fields -- both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote storage locations. Instead, properties have accessors that specify the statements to execute in order to read or write their values. Properties thus provide a mechanism for associating actions with the reading and writing of an object's attributes, and they furthermore permit such attributes to be computed.
In C#, properties are defined using property declaration syntax. The first part of the syntax looks quite similar to a field declaration. The second part includes a get accessor and/or a set accessor. In the example below, the PropertyDemo
class defines a Prop
property.
public class PropertyDemo {
private string prop;
public string Prop {
get {
return prop;
}
set {
prop = value;
}
}
}
Properties that can be read and written, like the Prop
property in the PropertyDemo class, include both get and set accessors. The get accessor is called when the property's value is read; the set accessor is called when the property's value is written. In a set accessor, the new value for the property is given in an implicit value parameter.
A property can be read and written in the same way that fields can be read and written. For example, the following code instantiates the PropertyDemo class and writes and reads its Prop property.
PropertyDemo pd = new PropertyDemo();
pd.Prop = "123"; // set
string s = pd.Prop; // get
In Java, when you pass a primitive as a parameter to a method, the parameter is always passed by value -- i.e., a new copy of the parameter is created for that method. In C#, you can pass a primitive (value type) by reference. If you do this, the method uses the same variable passed to it -- i.e., if you change the value of the value type passed, the original variable is changed.
To pass a value type by reference in C#, you use the keyword ref
. For example, if you compile and run the following C# code, you will get 16 in the console. Note how the value of i
is changed after being passed to the ProcessNumber method.
using System;
public class PassByReference {
public static void Main(String[] args) {
int i = 8;
ProcessNumber(ref i);
Console.WriteLine(i);
}
public static void ProcessNumber(ref int j) {
j = 16;
}
}
There is also another keyword named out
. This is similar to ref
, allowing a value type to be passed by reference; however, the variable passed as the parameter does not have to have a known value before the passing. The example above will generate an error message if the int i
is not initialized before being passed to the ProcessNumber method. If you use out
instead of ref
, you can pass a value that has not been initialized, like in the following modified example.
using System;
public class PassByReference {
public static void Main(String[] args) {
int i;
ProcessNumber(out i);
Console.WriteLine(i);
}
public static void ProcessNumber(out int j) {
j = 16;
}
}
This time the class PassByReference
compiles fine, even though i
is not initialized prior to passing it to the method ProcessNumber
.
Developers who think they can handle pointers wisely and are happy with manual memory management can get some extra horsepower in performance by using the "old time" pointers which are neither safe nor easy. C# provides the ability to write "unsafe" code. Such code can deal directly with pointer types, and fix objects to temporarily prevent the garbage collector from moving them. This "unsafe" code feature is in fact a "safe" feature from the perspective of both developers and users. Unsafe code must be clearly marked in the code with the modifier unsafe, so developers can't possibly use unsafe features accidentally, and the C# compiler and the execution engine work together to ensure that unsafe code cannot masquerade as safe code.
using System;
class UsePointer {
unsafe static void PointerDemo(byte[] arr) {
.
.
..
}
}
Unsafe code is used in C# when speed is extremely important or when your object needs to interface with existing software, such as COM objects or native C code in DLLs.
Delegates can be thought of as function pointers in C++ and other languages. Unlike function pointers, however, delegates in C# are object-oriented, type-safe, and secure. And, while a function pointer can only be used to reference a static function, a delegate can reference both a static method and an instance method. A delegate is used to encapsulate a callable method. You can write a method in a class and create a delegate on that method. The delegate can then be passed to a second method. This second method can then call the first method.
Delegates are reference types that derive from a common base class: System.Delegate
. There are three steps in defining and using delegates: declaration, instantiation, and invocation. Delegates are declared using the delegate
declaration syntax. A delegate that takes no arguments and returns void can be declared with the following code.
delegate void TheDelegate();
A delegate instance can be instantiated using the new
keyword, and referencing either an instance or class method that conforms to the signature specified by the delegate. Once a delegate has been instantiated, it can be called using method call syntax.
In an object-oriented language, you normally work with objects, but primitives are also provided for the sake of speed, so you have a world of objects and another world of values. In this situation there is always a need to make both worlds able to work together. You invariably need a way to make references and values communicate.
In C# and .NET Runtime worlds, this "communication" problem is solved using boxing and unboxing. Boxing is a process to make value types look like reference types. Boxing happens automatically when a value type (a primitive) is used in a location that requires or could use an object. Boxing a value of a value-type
consists of allocating an object instance and copying the value-type
value into that instance.
Unboxing does the reverse of what boxing does. It converts a reference type into a value type. An unboxing operation consists of first checking that the object instance is a boxed value of the given value-type
, and then copying the value out of the instance.
Java tackles this problem somewhat differently by providing a class wrapper for each primitive, e.g. the Integer
class for int
and the Byte
class for byte
.
This article has shown you how C# and Java compare. They are very similar; however, it is probably too far to say that C# is a clone of Java. Things like object-orientation or intermediary languages are not new ideas. So, if you were to design a new object-oriented language that needs to run in a managed and safe environment, wouldn't you come up with something like C#?
Budi Kurniawan is a senior J2EE architect and author.
john meister, mstm
IT systems design and integration specialist