TechHui

Hawaiʻi's Technology Community

A 15 Minute Intro to C# for Java Developers

Intro
This is a quick intro to C# for Java developers. Why should you care what those C# guys are doing? If you are a pragmatic developer you know its good to have a few languages in your toolbox. If you are a member of the anti-Microsoft crowd, think of it as a way to "keep your enemies closer." :-) The C# language features added to Java 5 make it clear Sun and the JCP are taking this approach.

C# is a very close relative of Java. Its inventor, Anders Hejlsberg, clearly used Java as a starting point and added some useful features such as explicit language-level support for properties and events. C# 3.0 introduces type inference, python-like object initializers, and LINQ (Language Integrated Query).

Both languages are object oriented, compile to bytecode (called IL in .NET parlance), run on a virtual machine, include language level support for concurrency and execute in a garbage collecting runtime. Neither language allows multiple inheritance of classes. Both support multiple inheritance of interfaces. C# and Java share many keywords and have similar type systems. Learning the C# language is not overly difficult for a Java programmer. It can be accomplished in a weekend. You will spend more time learning the .NET libraries than learning the language. Luckily, many parts of the libraries such as the collection classes will also look familiar.

Requirements
Not surprisingly, the best tools for C# development are available for Windows. Microsoft offers a free IDE called Visual C# and a series of commercial IDEs called VisualStudio. There is also an excellent open source IDE called Sharp Develop. I learned a lot about C# by browsing the Sharp Develop code base. Its hard to compare VisualStudio and Eclipse, but suffice to say Eclipse has a better code editor while the VisualStudio line has better integrated tools for WYSIWYG UI creation and database tools. If you miss Eclipse's excellent code hints and other fancy editor features you can add most of them to VisualStudio by installing the excellent Resharper plugin from JetBrains.

If you are on a Linux, Unix or OS X box you are not out of luck. The Mono toolkit allows you to compile and run C# applications on these platforms. Unfortunately Mono doesn't yet support C# 3.0 features such as LINQ, but its a solid implementation of the original ECMA standard.

Getting Started: Aloha World
Lets dive right in with the classic Aloha World example:

class ExampleClass {    
static void Main() {
System.Console.WriteLine("Aloha world!");
}
}

Aside from different capitalization rules, this looks a lot like its Java equivalent. Methods and property names in C# start with capital letters by convention. This is annoying at first, but you will get over it.

Now lets take a look at some of the language features that are different. A simple Java POJO for a person:

public class Person {
private String name;
private int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age= age;
}
}

The equivalent class in C#:
public class Person {
private String name;

public String Name {
set { name = value; }
get { return name; }
}

public int Age {
set { age= value; }
get { return age; }
}
}

C# provides language support for properties rather than relying on naming conventions. The advantage is terser code that is less error prone and more perspicuous. Properties in C# are accessed like so:

    int age = joe.Age;

To a Java programmer this may appear to be direct variable access, but this is not the case. Properties provide the same encapsulation as methods.

As of C# 3 we can make use of automatic properties for an even terser definition:

public class Person {
public string Name { get; set; }
public int Age { get; set; }
}

Thanks to object initializers we can instantiate this class using any combination of properties without having to create a lot of overloaded constructors. Object initializers allow us to easily set any property in any order. They are also much easier to read.

    var child = new Person { Age=8 };
var ted = new Person { Name="Ted" };
var joe = new Person { Age=20, Name="Joe" };

What are those "var" types in the example above? Is this VB style loose typing? It is not. Type inference allows us to use var for local variables and have the compiler substitute the type. This is completely type safe and can save us a lot of typing, especially when dealing with long generic type definitions. This brings us to our next topic: type systems.

Type Systems
Java and C# (or more accurately, .NET) have similar type systems. Both languages have objects and primitives. As of Java 5 both languages support easy coercion between objects and primitives via boxing and unboxing. Whether or not this is a good idea is a topic of heated debate. C# has more built in types including unsigned integer types and a very handy 128-bit decimal type useful for performing financial calculations.

Java and C# take a different approach to generics. Neither is similar to C++. In Java generics are implemented using a technique called erasure. In short, the compiler removes the type parameters and inserts casts. The advantage of this approach is that generic classes are interoperable with non-generic (legacy) classes. Java 5 didn't have to introduce a new generic ArrayList class. The developers simply added a type parameter to the existing ArrayList. The disadvantage is that type parameters cannot be reflectively discovered.

.NET introduced type parameters to the intermediate language (IL). They sacrificed interoperability for the ability to discover type parameters at runtime. This provides a lot of advantages, especially for tools that use reflection, but the lack of interoperability is a real PITA.

C# also provides some C++ like features in its type system such as user defined structures (value types.) All the wrapper types in C# are implemented as structs.

Example struct definition:
public struct Point  {
public int x, y;

public Point(int p1, int p2) {
x = p1;
y = p2;
}
}

Using structs can yield efficiencies because they are instantiated on the stack rather than the heap, but Java developers must be careful to note the copy on assignment behavior.

Example:
    var pointA = new Point(3, 5);
// point B is a copy of point A
var pointB = pointA;
pointB.x = 10;

// result: 3. pointA is unchanged.
Console.WriteLine(pointA.x);

Method Overriding - A Java to C# Gotcha
The difference in method overriding behavior of C# and Java has been a source of great confusion. In C#, methods are not virtual by default as they are in Java. Methods with the same name and signature hide the method of their superclass by default. Only with use of the override keyword does the Java-like behavior come into play.

Java Example:
    public class Cat {
public void makeSound() {
System.out.pringln("purrr");
}
}

public class Lion extends Cat {
public void makeSound() {
System.out.pringln("roar");
}
}

Cat cat = new Lion();
cat.makeSound();

// result: roar

C# Example:
    public class Cat {
public void MakeSound() {
Console.WriteLine("purrr");
}
}

public class Lion : Cat {
public void MakeSound() {
Console.WriteLine("roar");
}
}

Cat cat = new Lion();
cat.MakeSound();

// result: purrr

If we rewrite the C# example with the override keyword the results are identical to Java:

    public class Cat {
public virtual void MakeSound() {
Console.WriteLine("purrr");
}
}

public class Lion : Cat {
public override void MakeSound() {
Console.WriteLine("roar");
}
}

Cat cat = new Lion();
cat.MakeSound();

// result: roar

LINQ: C#'s Most Interesting Feature
C# 3.0's LINQ (Language Integrated Query) is perhaps its most interesting and compelling feature. LINQ allows us to query and transform databases, XML structures, object graphs and collections without embedding another language in a string. The advantages over embedded SQL, OQL and HQL strings are manifold. We only have to learn one language to query a wide variety of data structures (persistent and in-memory), the compiler can statically check types and syntax, and it makes programs much easier to read and comprehend.

Here is a simple in-memory example of finding the sum of numbers in a range:

    int[] numbers = { 5, 4, 3, 9, 8, 6, 7 };
var lowNums = numbers.Where(n => n>5 && n<8);
Console.WriteLine(lowNums.Sum());
// result: 13

This can also be written is a more SQL like manner:
    var lowNums = from n in numbers
where n > 5 && n < 8 select n;

Microsoft has a great list of LINQ Examples.

Comparative Examples
We will finish with a couple examples of common tasks in Java and C#.

Writing text to a file (exception handling omitted):
Java
    FileWriter writer = new FileWriter("/examples/text.txt");
writer.write("My text");
writer.close();

C#
    StreamWriter writer = File.CreateText("/examples/text.txt");
writer.WriteLine("My text.");
writer.Close();

Synchronizing (locking) an instance method:
Java
    public class Cache {
public synchronized void add(Object cacheMe) {
list.add(cacheMe);
}
}

C#
    public class Cache {
public void Add(Object cacheMe) {
lock(this) {
list.Add(cacheMe);
}
}
}

Summary
C# is a rich language worth exploring. I expect we will see the Java equivalent of LINQ sometime around Java 8 (its probably too late to get it into Java 7.) While participating in JCP expert groups I always check to see what Microsoft is up to. Whether or not you are a fan, its good to have a well rounded knowledge of what is happening in the wider development world.

As always, comments, corrections, questions and creative insults are welcome.


Ikayzo - Design • Build • Localize | Web • Desktop • Mobile

Views: 40281

Comment

You need to be a member of TechHui to add comments!

Join TechHui

Comment by Daniel Leuck on March 29, 2008 at 5:27pm
Nice article. I'm actually a C# 2.0 developer and know enough Java to read the language.

Thank you. C# 3.0 is a big language. I've been studying it for a while and I still see examples that send me scrambling for the language spec :-)

Looks like I'll be adding C# and LINQ to my to-learn list this year.

I found Pro LINQ by Joseph C. Rattz very helpful.
Comment by Stephen Figart on March 29, 2008 at 4:59pm
Nice article. I'm actually a C# 2.0 developer and know enough Java to read the language. I'm still figuring out C# 2.0 features like the yield keyword, and I'm no power generics user, but I do try. Looks like I'll be adding C# and LINQ to my to-learn list this year.

Sponsors

web design, web development, localization

© 2024   Created by Daniel Leuck.   Powered by

Badges  |  Report an Issue  |  Terms of Service