C# for Java Developers, Part I
C# (pronounced see sharp) first appeared in the year 2000, 5 years after Java. It’s currently at version 7, which was released in March this year. The language is similar to Java in many ways, but it’s also very different. Both Java and C# are typed statically and strongly, object orientated, use curly braces to define scope, and semi colons to indicate line endings. While they have similar syntax, the C# syntax differs enough from Java that it might look a bit confusing to a long time Java developer at first sight.
The structure of this guide is as follows: Each hand picked topic consists of three sub sections. One code sample from each camp, and then some quick bullet points that cover what I consider the most important takeaway from the particular subject. All code you see is also available in the C# for Java Developers GitHub repository.
A word of warning: I’m writing this guide as I learn C# myself, so don’t except everything to be 100% accurate. Consider reading this as a way to kick start your own C# adventure.
Without further ado, let’s jump in the deep end of the pool.
Code structure
We’ll begin like we always do when we’re learning a new language: Hello, World! It’ll fill us in on the basics. First, your familiar piece of Java code, then the mystery that is C#:
package net.vegard.csharpforjavadevs.structure;
public class Example {
public static void main(final String args[]) {
System.out.println("Hello, World!");
}
}
using System;
namespace VegardNet.CSharpForJavaDevs.Structure
{
class Example
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}
}
- In C#, class names and file names do not have to match. In Java, they do.
[namespace](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/namespace)
is C#’s version of Java’spackage
.- Unlike Java, C# files don’t have to be in a directory structure that match its
namespace
. Microsoft has a useful namespace naming guideline. - A
namespace
, andpackage
for that matter, defines your code’s scope. The C# way to do it seems semantically more correct than the way it’s done in Java, but it adds extra white space to your code. - The C#
[using](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive)
keyword is similar to Java’simport
keyword.using
refers to a class’namespace
. In the example above, theConsole
class lies within theSystem
namespace. - By adding using
System
on line 1 in the C# example, I can writeConsole.WriteLine
on line 9. Otherwise, line 9 would have to readSystem.Console.WriteLine
. - The C# code style convention is a little bit different than Java’s, but it’s nothing that’ll require you to rewire your brain:
- Starting curly brackets are place on a new line.
- Everything, except for variable names, keywords, and built-in data types, start with a capital letter.
- C# Programming Guide: Coding Conventions.
Classes
In it’s most old-fashioned form, C# classes look almost exactly like Java classes1.
package net.vegard.csharpforjavadevs.classes;
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
namespace VegardNet.CSharpForJavaDevelopers.Classes
{
public class Student
{
private string name;
public Student(string name)
{
this.name = name;
}
public void SetName(string name)
{
this.name = name;
}
public string GetName()
{
return name;
}
}
}
- The C# constructor looks the same as in Java; it’s a method without return type, and with the same name as the class.
- Like in Java, a default constructor will be generated by the compiler if the class doesn’t contain one.
- Also like in Java, if the class contains a parameterized constructor, a default constructor will not be generated.
- In addition to the access modifiers you know from Java,
public
,private
,protected
, and the default modifier, C# also supports[internal](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/internal)
. I’ll discuss access modifiers in detail later. - C# supports the same one-class-only class inheritance as Java. The
:
character is used to indicate that a class inherits from another. So forclass A : B
, class A inherits from class B. The Java equivalent would beclass A extends B
. - When using class inheritance, members of the parent class can be accessed using the
base
keyword, which is equivalent to Java’ssuper
keyword. Note, however that there’s a significant difference in the syntax when calling parent constructors, as described in Using Constructors chapter of the C# Programming Guide. - If you want to prevent other classes to inherit a class, you can use the
[sealed](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed)
keyword, as insealed class MyClass
. The Java equivalent would be to use thefinal
keyword. - Like in Java, classes can be declared
[static](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/static)
and[abstract](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract)
. - C# Programming Guide: Classes and structs.
Interfaces
There are no big differences between an interface in Java, and an interface in C#.
package net.vegard.csharpforjavadevs.interfaces;
public interface Reportable {
void generateReport();
}
namespace VegardNet.CSharpForJavaDevelopers.Interfaces
{
interface IReportable
{
void GenerateReport();
}
}
- Visual Studio will throw a fit if an interface doesn’t begin with a capital I.
- Just like a Java interface, you can’t create an instance of a C# interface.
- A C# class that implements an interface must provide an implementation of all methods defined by the interface. Just like in Java.
- A class implements an interface by using the
:
character, the same character used for class inheritance. This is different form Java, where the two actions have different keywords,implements
, andextends
, respectively. - As far as I can tell, there is not C# interface feature equivalent to the default methods you can create in a Java interface.
- C# Programming Guide: Interfaces.
Wrap up
That’s it for now. It’s important that your first bite of the C# cake isn’t too big, or you’ll get a bellyache. So far, this looks like a solid case of Same Shit, Different Wrapping. But don’t despair. First, we need to cover the basics. Then, we’ll get to the juicy stuff.
If you have any corrections, information you think can be useful, or just general praise, please post a comment.
Part II of this guide will be published When It’s DoneTM.
Yes, I know the C# example below can be written a lot more elegantly. I’ll get to that later, so please hold your angry comments and hate mail. ↩︎
Feedback
Do you have any thoughts you want to share? A question, maybe? Or is something in this post just plainly wrong? Then please send an e-mail to vegard at vegard dot net
with your input. You can also use any of the other points of contact listed on the About page.
Congratulations, I can guarantee you it is a better journey then the other way around as I’ve done :).
Some corrections/additions (which you probably will fix in the next post as stated in footnote 1 :)):
Namespace do control scope, but also be aware that project does so too. That is when the internal keyword might come in handy, that is making something visible everywhere in a project but not outside the project.
Code structure is the same, but you usually don’t use getName or setName in C#. If there are plain getters and setters you should use: public string Name { get; set; }
I don’t think you need to use this in this.name = name, but not 100% sure since I haven’t done that much C# the last year (mainly play around with F#)
Thanks a lot for your feedback, this is exactly the kind om looking for. The plan is to cover the magic of properties in a later post, but probably not before the third or even fourth part. There’s a lot of basic stuff to cover first.
I’ll take a dive into project scope, and try to wrap my head around it, and I’ll also give skipping this a try. Thanks again.
I tested removing the this from this.name = name, and while it compiles, it creates a bug since the class’ name member isn’t being assigned to anything. The constructor and SetName input parameter is assigned to itself. This makes sense. Visual Studio will display a warning if this is removed.
Someone recently told me that using should go inside the namespace, and I have adopted that style. It makes a lot of sense. You are importing the things into the namespace, so it seems like a better choice.
Default implementations is coming in the next version of C#, I think.
When it comes to inheritance, methods have to be marked as virtual to be overridden in a subclass. This is super annoying if you are coming from java, because it can make it really hard to write test fakes.
Yeah, using using inside of the namespace makes a lot of sense. Great tip. Coming from the Java world, I just assumed that it had to be the at the beginning of the file. As for testing, I suspect that writing proper unit tests in C# should be an entire guide by itself.
Looking forward to read the other parts!
Yeah, so do I ;)