This file is part of a multi-series workshop on learning C# on Linux available here.
Author: Martin Woodward
Before you start you want to make sure that you have .NET Core installed and configured in your path
dotnet --version
Assuming the command above works, you are good to go! If not, please see Tutorial 1 - Getting Started with C# on Linux.
Now you have .NET Core installed, let's create our first C# program. To begin we need to create a folder to store our C# code project in, i.e.
mkdir -p ~/source/dotnet/002-hello
cd ~/source/dotnet/002-hello
Then we want to create a new C# project in it
dotnet new
This will create the following files in that directory
- Program.cs - the actual program, with a basic Hello World sample ready to run
- project.json - a meta-data file that describes the entire .NET project to the compiler and other tooling.
Now we have an application, the next thing we have to do it tell NuGet to download the dependencies we need for our project. Do this by typing
dotnet restore
Then to build and run your application, simply type
dotnet run
That's all there is to it. Now let's take a look at Program.cs
and make some changes.
Open Program.cs
in your favorite editor and take a look at the contents. After you ran
dotnet new
the following file would have been created
using System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Note that C# ignores whitespace so while the code above is indented for readability it is not required.
Lines of code are terminated with a semi-colon (;
) and blocks of code are grouped using curly braces ({ }
).
The .NET Core codebase itself uses use Allman style
braces, where each brace begins on a new line. A single line statement block can go without braces but
many developers enjoy debating if that is evil
or not. (It is)
The first line you see is the using
directive. using
is similar to import
in other languages like Java, Python or Go.
It tells the C# compiler where to find
the classes that you want to call. In the example above, the full name of Console
is actually
System.Console
but the using System
directive means that the compiler automatically looks
for the Console
class with-in the System
namespace.
A namespace
is a way of grouping classes together in a way that limits their scope and avoids name
conflicts. This is similar to package
in Java however in C# while it is convention to have a hirerarchy
of namespaces represented as a tree structure in a directory, you don't have to. A single .cs
file
could declare multiple classes in multiple namespaces - though that would be a little bit evil. In the
example code created, you are defining Program
to live in the ConsoleApplication
namespace, therefore
the full name of the class would be ConsoleApplication.Program
.
In .NET, code is organized into assemblies
- a package of one or more namespaces of code in a shared library (a DLL) or an executable. Shared libraries (including the .NET Framework itself) are typically grouped into NuGet packages for distribution.
A C# program must contain a public static
method called Main
which controls the start and end of
the process and there can only be one Main
method per project. When the program is executed
the .NET runtime will look for the class containing the 'Main' method and execute it. You can
change the class name and namespace in your example and the Main
method will still execute when
you run the application.
You can declare the Main method in two ways:
public static void Main(string[] args)
{
// Do Something
}
Which would always return a 0
exit code, or if you want to have control of the exit codes
returned by your application you can declare your exit code explicitly by indicating that your
Main
method returns an int
and then returning an integer in your Main
method.
public static int Main(string[] args)
{
// Do Something
return 0;
}
You can run the code above and verify the exit code returned by typing
dotnet run
echo $?
Note in the example above, we are showing comments. In common with many languages C# supports C style comments, i.e
int x = 1; // Single line comment
/* You can always
* spread you comments out over many lines
*/
In the example above, the Main
method was declared with a visibility of public
so that is can be accessed
by code in the same assembly of any assembly that references it. The other most common access modifier to
control visibility is 'private' which means the code can be accessed by the same class or struct. 'protected'
means that the code can be accessed by the class or anything that derrives from that class and 'internal' code
can be accessed by any code in that same assembly but not from another assembly. Note that in C# the access
modifier visibility is scoped at the assembly level not at the namespace level. For more information on all
the access modifies in C# please see the
reference documentation.
- Create a new .NET Project and run it.
- Modify the program to change the message it returns and run it.
- Modify the program to return an exit code of 1.
In this tutorial we learned how to create a new C# application, the structure of a basic C# program, how to run the application and how to change the exit code of the process.
- Using directive in C#
- Namespaces
- System.Console
- Main() and Command-Line Arguments
- Visibility and Access Modifies in C#
- NuGet
- project.lock.json
- Next: Tutorial 3 - C# Language Basics
- Previous: Tutorial 1 - Getting Started with C# on Linux
- Back to Table of Contents