Say "hello" to the world
As you saw in the video, a function is a block of code with a name that performs a service. When it comes to a Main
function, the service it performs is actually the program itself! Cool, right? When a function is located inside a class, it is called a method. Since all C# code is located inside classes, you can use both terms (functions and methods) interchangeably. 😎
Now that you know about Main
functions and starting a program, let's write one! When learning a language, the tradition is to write a first program that outputs the Hello World! string.
Here is the C# code honoring this tradition:
using System;
namespace Hello
{
/// <summary>
/// This is an implementation of the traditional "Hello world!" message
/// </summary>
/// <remarks>Created by the OpenClassrooms Education Team</remarks>
public class HelloWorld
{
/// <summary>
/// This is where the program starts
/// </summary>
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Let's break this code down:
The first statement,
using System;
is a using directive. It tells the compiler which namespaces it should reference to find the classes you use in your code. A namespace organizes a related set of C# classes. TheSystem
namespace contains fundamental and base classes that define commonly used value and reference data types, events and event handlers, interfaces, attributes, and processing exceptions.The second statement,
namespace Hello
, is a namespace declaration. When writing a simple program, you can use the same namespace name for all your files.The
public class HelloWorld
declaration defines the name of the class asHelloWorld
. In C#, all code must reside inside a class. You will find yourself writing and using two kinds of classes:Classes that serve as a blueprint for objects, as you saw in the Define objects chapter. Those classes define the state of the object with fields, and its behavior with methods.
Utility classes that serve as containers for operations you want to perform, but do not need a persistent state. Those classes generally contain no fields.
Inside the class, you will find the
public static void Main(string[] args)
function declaration. This is the piece of code that the C# interpreter looks for when you start a program.Inside the
Main
method, you find theConsole.WriteLine("Hello World!");
statement that prints the expected message.In case you're curious, the lines within the
///
characters are documentation comments. This makes it possible to automatically create an XML file which can be turned into HTML web pages containing the documentation for your code. It usually contains a list of classes, methods, and variables, as well as comments. This allows other programmers to use your code without having to go through your actual C# code. Handy, huh? For now, you'll be able to recognize what those lines do, but we'll come back to this at the end of the chapter. 😇
To sum up, the starting code for a C# program is contained inside a Main function (or method). This Main function is contained inside a class. Finally, this class belongs to a namespace.
Now that you know how to write the code, it's time to run it!
Run the program
In C#, it is a common practice to have the file structure match the namespaces and classes. In other words, to run the program on your computer, create folders that correspond to your namespaces and files that correspond to your classes! For the moment, our Hello World! code is written inside the Main method of a HelloWorld class, which is located inside a Hello namespace. Now, let's check out what you have to do to map this with some files and folders.
There are a few key steps:
First, create a folder where you will put all of your code. This is typically called the root folder.
Inside this root folder, you can create a "Hello" folder to match the name of your namespace.
Next, create a HelloWorld.cs file inside the "Hello" folder to match the name of the class.
See how this all maps out? Namespace to folder, class to file ✅. Once the HelloWorld.cs file is created, you can type in your C# code. Use the code from the previous section:
using System;
namespace Hello
{
/// <summary>
/// This is an implementation of the traditional "Hello world!" message
/// </summary>
/// <remarks>Created by the OpenClassrooms Education Team</remarks>
public class HelloWorld
{
/// <summary>
/// This is where the program starts
/// </summary>
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
When all the code is inside the file, you need to convert this C# code into a machine-executable code the computer can understand.
What does "machine-executable" mean?
Regardless of the programming language you are using to write your code, it must be translated to a set of instructions that a computer can run. This is called machine code.
Why don't we write programs directly in machine code?
Even though the machine code is very clear to computers, it would be difficult for humans to understand. Think of it as a cooking recipe; you can use a spoken language to describe the ingredients and the instructions, or, you can use their chemical contents and jargon. It may be understood by some; however, for most of us, cooking would be out of reach. Even for those who know chemistry, it would turn into a very long process! Don't you agree?
Organize your code to keep your Main as small as possible
The purpose of the Main
function is to start your program. If you were to provide all the statements your program logic requires inside the Main
, it would quickly become impossible to read and understand. This would make it tough to maintain your program. This is why you need to organize your code into classes.
As we said at the beginning of the chapter, there are two kinds of classes you can write and use.
Classes as blueprints for objects
As seen in the first part of this course, you can define complex types that put together different attributes representing a named concept called blueprint classes. They should model the domain of your application - what you are creating your program to do.
The String
class used to store and manipulate strings in your program is an example. This class is in the System
namespace, which is available from any part of your code.
You can also use the alias, string
, for String
when you’re referring to an object. If you need to refer to the class specifically, then use String
.
How is String
a class and not a primitive type such as int
or double
?
String
is a class not only because its name starts with an uppercase letter, but because it defines a state and a behavior:
Its state is the character strings you are storing. The actual value is set for each object when you instantiate it.
Its behavior is the set of methods the
String
class defines that let you operate on that string you store.
Let's see this in action:
using System;
namespace StringDemo
{
public class StringDemo
{
public static void Main(string[] args)
{
// Declare and create a string
string shockingSentence = "The C# String type actually is a class, not a simple type!";
// Say it out loud
Console.WriteLine(shockingSentence.ToUpper());
// Replace one word with another
Console.WriteLine(shockingSentence.Replace("simple","primitive"));
}
}
}
The List
class is another type of blueprint class which we already covered. It offers all the functionalities you need from a list. You need to instantiate a new object for each list in your program. Each object will contain its own list elements.
The second type of class you will define and use: utility classes.
Utility classes as support for your code
You've also used the System
class. Remember? We just used it to print a string!
Let's break down the statement of our first program:
Console.WriteLine("Hello World!")
Console
is the name of a class.WriteLine
is a static method that performs the printing operation and goes to a new line.
The WriteLine
method is defined as "static," which means you don't need to instantiate an object to use it. This is why you are calling the method directly on the System
class.
Another example of a utility class is the Math
class.
The Math
class defines common operations you can perform on numbers. For instance,Math.Abs(-4);
will result in the absolute value of the provided value, which is 4
in that case.
Static methods defined in utility classes are useful because they let you extract functionality into a reusable block of code. You can then use them without having to instantiate an object. This means you have no excuse for a lengthy Main
!
Clean up your Main
To complete this chapter, let's apply a fundamental concept to make your code understandable and maintainable: do not keep anything inside the Main
that can be extracted to a function. Even if your current implementation consists of a single statement, you should replace it with a call to an actual method that does the work. If you decide to add more complexity, it will be moved to other methods, keeping the Main
clean.
Let's get control of your Main
and make it as clean as possible. Here is a clean implementation of the HelloWorld program:
using System;
namespace CleanHello
{
/// <summary>
/// This is a clean implementation of the traditional "Hello world!" message
/// </summary>
/// <remarks>Created by the OpenClassrooms Education Team</remarks>
public class CleanWorld
{
/// <summary>
/// This is where the program starts
/// </summary>
public static void Main(string[] args)
{
SayHelloTo("World");
}
/// <summary>
/// Displays a hello message to the provided recipient
/// </summary>
/// <param name="recipient">Who to say hello to</param>
private static void SayHelloTo(string recipient)
{
Console.WriteLine("Hello " + recipient + "!");
}
}
}
As you can see, the CleanWorld
class defines two methods:
Main
is the starting point of the program. Its only job is to hand over the work to the SayHelloTo method with the argument it needs. In our case, this is the predefined recipient to our hello: the world!The
SayHelloTo
method prints the "Hello" string and appends the value provided to therecipient
variable whenever it is called by theMain
method.
In terms of functionality, nothing has changed. However, you can now add more logic to the message you display by changing the SayHelloTo
method and personalizing the recipient name.
We'll add functionality in the following chapters! For that you need to add more logic to your C# programming tool belt. The next chapter covers the first tool: conditions!
Let's recap!
In this chapter, you have seen that:
C# programs are structured into namespaces and classes.
No code is written outside of a class, which means that all functions are methods in C#.
It is common practice to have namespaces map to folders and classes to files.
Classes come in two types:
Blueprint classes, which are used as models for the instantiation of objects.
Utility classes, which contain static methods that can be called directly on the class.
Clean code principles mandate that that no logic is written inside the
Main
method. All work should be delegated to properly named functions.