C#: Hello World

Let’s write some actual code today and there are few places better to start than with the traditional ‘Hello World’ program.

For this post, I want to give an introduction to writing our first functional C# program. It will not do much but hopefully, for those new to software development it will be interesting.

We’ll develop the app by using PowerShell (or command line but some of the commands will be different) and a simple text editor (Notepad) but if you want to you can follow through in Visual Studio, I’ve put a setup guide together for Visual Studio 2017 if you need/want it.

The first thing we’ll do is check we have dotnet installed. Open PowerShell and run the command

dotnet --version

You should see something along the lines of the following:

dotnet version

If you don’t see this or you’re told dotnet isn’t installed, check out this guide to install it.

Great, so dotnet is installed and we can now start writing our code.

We’ll want to go ahead and create our project directory and change into it.

mkdir hello_world
Make project directory

Now that we have our project directory we can create the project itself. We are going to be making a console app and all we want it to do is print ‘Hello World!’ to the console. The easiest way to create the app is from the command line, as we are there already. There are a few options available to us, and not just for console apps, but I’ll put a post together about that another time. For now, we just want a console app created with the following command.

dotnet new console
dotnet new console

We should now have two files inside our hello_world directory, a Program.cs file and a hello_world.csproj file.

new project contents

The Program.cs file will contain our code, it currently has the default codebase provided by dotnet for a console app, shown below in the red box.

Some of you may notice that it appears this app does what we want it to already. We’ll make some changes so we can introduce some other components in software development.

The hello_world.csproj file is our project file, this is an MSBuild project file for a C# project. It contains information about the project and how to build it. For the purposes of this post, its not something we need to worry about just that we need the default.

Let’s modify our Program.cs file to provide us with a bit more to work with, to open the Program.cs file in a text editor (on Windows) run the following command in the hello_world project directory.

Notepad Program.cs
Open Program.cs in Notepad

This will open the Program.cs file in Notepad as shown below.

Program.cs open in Notepad

Great stuff, now let’s make some changes. Update your Program.cs file inline with the code below.

using System;    // 1. Importing namespace

namespace hello_world    // 2. Hello World namespace
{
    public class Program    // 3. Class declaration
    {
        static void Main(string[] args) // 4. Method declaration
        {
            string helloWorldMessage = "Hello World!"; // 5. Statement 1
            Console.WriteLine(helloWorldMessage); // 6. Statement 2
        } // End of Method
    } // End of Class
} // End of namespace

Now that we have some code to work with let’s go through it.

Firstly, I’d like to explain what ‘//’ means, everything on the line after the ‘//’ is called a comment and is ignored by the app. That means it doesn’t matter what we put there the compiler isn’t interested in it. The text (in grey) is for humans only.

Now let’s start going over the code line by line.

using System;

This line allows us to reduce our codebase, by including it we don’t have to specify the fully qualified domain name to access the contents of the System namespace. See the below example

// Without 'using System;' we'd have to use the fully qualified domain name to use WriteLine
System.Console.WriteLine(helloWorldMessage);

// But because we did include 'using System;' at the beginning we can omit it and still access WriteLine
Console.WriteLine(helloWorldMessage);

Following that, we have our namespace declaration.

namespace hello_world
{
... // Rest of the code.
}

The first line declares the name of the namespace which is hello_world, think of a namespace as a container so we can organise our code. Everything between the opening { and closing } is contained within the scope of the namespace and so is part of it.

NOTE: Any code caught between ‘{‘ and ‘}’ is said to be in the scope of whatever created that scope; namespaces, classes, structs, methods, loops etc.

Next up we have our class definition:

public class Program
{ // No need to talk about scopes again
... 
}

To define a class with follow the class definition syntax

// [access modifier] - [class] - [identifier]
public class Program

Our access modifier is public, there are several access modifiers in C# but for now public means this class can be accessed by any other code either in the assembly or any other assembly that references it. We can skip adding the access modifier and the compiler will then use the default internalwhich allows only code in the same assembly to use it.

NOTE: If you omit the access modifier anywhere in C# the complier will plug in the most restricted access that can be declared for that member.

As we are creating a class we use the class keyword to define it as such.

Finally, we provide the identifier for the class, that is we provide the name and for us that’s Program.

Next, we define the first and only method within our Program class, called Main

As with a class definition we have a set method definition syntax we can follow.

// [access modifier] - [optional modifier] - [return type] - [Identifier] (Parameter List)
static void Main(string[] args)

Main‘ is important as it is the entry point for our program, this is where the app starts from as far as we are concerned. Interesting because the ‘Main‘ method is marked as the entry point in IL, see this post for more information on how .Net works, it doesn’t have to be marked with an access modifier, i.e. made public, because behind the scenes the CLR knows where to start from.

First up then we have the static keyword which is an optional modifier. Because Main is our entry point we don’t need to worry about static for now but I’ll link to the relevant post explaining static in detail in the future. For now, if you’ve read my OO post static associates the method with the class and not with an object created from the class.

Next is our return type, by default, we don’t return anything from
Main so we use the keyword void to identify it as such however this can be any data type. Traditionally the type has been returned by value but as of C# 7.0 it can not be returned by reference, again not something to worry about now, I’ll do a post explaining value and reference types.

Following our return type, we have the identifier, again this is the name. Quite straight forward this one, the name is ‘Main‘.

Finally, we have our parameter list, this is simply a list of 0 or more types and names required by the method and the corresponding arguments provided by the client. In this case, it would be any arguments passed in when starting the app.

NOTE: To confirm and avoid any confusion in the future, a method defines what parameters are required and a caller of the method provides arguments for each parameter.

Now that we have our method defined we can move onto our first (and only) statement block, this contains the statements (actions) which are performed sequentially within the scope of the method.

We have two statements, the first:

string helloWorldMessage = "Hello World!";

This is a declaration statement, we are declaring a new local variable of type string and naming it helloWorldMessage. We use an expression to assign the value “Hello World!” to our new variable using the assignment operator ‘=‘. To access the value of the string we then use helloWorldMessage, as shown in the next line.

A variable is a storage location which can contain different values over time but not different types, this is because C# is a strongly-typed language. We must know what each storage location will contain at compile time. So each variable is of a specific type and the type defines the characteristics of the storage location. In our case, we have a string type which means we can only put text (a sequence of read-only characters) into our storage location.

Our next statement is:

Console.WriteLine(helloWorldMessage);

Here we are using a method provided by .Net Core found in the System namespace. The method itself is static, provides no return type, and is in the Console class. There are multiple versions of the WriteLine method each having a different collection of parameters. For us, the parameter is a string, as we are passing in our string contained in helloWorldMessage, so we are using the following fully qualified Console.WriteLine

System.Console.WriteLine(string value);

This method, as described by the Microsoft documentation:

Writes the specified string value, followed by the current line terminator, to the standard output stream.

The remaining content in the file is scope closing ‘}”s described above.

Ok, so we’ve written our program and we’ve worked through it and have an understanding of what each part does. Now let’s run it.

In your terminal, make sure you’re inside the project directory, run the following:

dotnet run

This will build our code using the dotnet build command and then run it for us. You should see something shown below.

dotnet run

Congratulations. Doesn’t do much and has no real value except to us but a ‘Hello World’ app is the starting point for almost all developers.

I’ll add a post providing C# keywords.

For now, why not play around with it and have it print different things to the screen. For those, a bit more curious you might’ve noticed my text is a different colour to yours, have a go and find out how you can change the text colour from inside your app.

Update: Code can be found here.

Comments

Let’s take a look at Comments in our code.

After reading Uncle Bob’s book “Clean Code” my view of writing comments (writing code in general really) changed. Although for the purposes of a portfolio I aim to provide comments within my codebase I don’t think comments are as crucial as we are led to believe.

Why?

Because we should be writing expressive code. It’s our code that should be acting as the comments because the code itself should be well written. There is one quote that has sort of stuck with me “The proper use of comments is to compensate for our failure to express ourself in code.” (Clean Code, Pg. 54). It’s the use of the word ‘failure’ I found most interesting, within the book we are told that we should write our code as if we were writing a story. So if we are writing the story well we shouldn’t need to give the reader any additional information through the use of comments.

Granted this is not always the case and sometimes a comment is very useful where perhaps the algorithm we’ve written is particularly complex, for whatever reason, and the comment will ensure future developers (including ourselves) can understand our intent.

A very simple example below shows how being more expressive when writing our code could remove the need for a lot of comments.

// Seconds since machine was started
int ssb = GetSecondsSinceMachineBooted();

instead, we could, in conjunction with good use of Names,

int secondsSinceMachineBooted = GetSecondsSinceMachineBooted();

as mentioned very simple and yet throughout the code, there is no need for mental mapping. Every time the reader sees this they don’t need to refer back to the original comment to remember what the ‘ssb‘ stood for.

Another consideration we should make when writing comments is, ‘Am I or anyone else in the future likely to update the comment in line with code changes?’.

There have been times where we have all looked at code and the comment doesn’t actually match what the code is doing. Meaning the comment possibly describes what the code used to do and not what it actually does now. Not only does this increase confusion but if the original code had perhaps been written in a more expressive context then the comment would not have been needed at all.

While my opinion does lean more heavily towards avoiding comments and using our code to convey our intent I accept we cannot always work this way. One obvious exception and it is one we see all around us, in software anyway, is the use of style guides.

I use StyleCop for my C# development because it enforces consistency across all my projects. Specifically, in the context of code comments, I limit the use to the bare minimum required by StyleCop. The intention here is that as and when required documentation can be autogenerated from the codebase (including comments) and distributed without the need for a separation between the code and that documentation. Additionally, by developing against the StyleCop default enforcements we provide users of our code with extra information through Visual Studios Intellisense.

At the end of the day when it comes to comment I think the easiest way is to simply ask ‘Is this comment needed? Can I expressive it in the code?’.

Just to wrap up, as I’ve said before if you haven’t already I would recommend you check out Uncle Bobs Clean Code book. I believe it has had a very positive impact on how I develop my software.