Getting started with .NET Core on Windows/Linux/macOS using the command line

This topic will show you how to start developing cross-platforms apps in your machine using the .NET Core CLI tools.

If you're unfamiliar with the .NET Core CLI toolset, read the .NET Core SDK overview.

Prerequisites

Hello, Console App!

You can view or download the sample code from the dotnet/samples GitHub repository. For download instructions, see Samples and Tutorials.

Open a command prompt and create a folder named Hello. Navigate to the folder you created and type the following:

$ dotnet new console
$ dotnet run

Let's do a quick walkthrough:

  1. $ dotnet new console

    dotnet new creates an up-to-date Hello.csproj project file with the dependencies necessary to build a console app. It also creates a Program.cs, a basic file containing the entry point for the application.

    Hello.csproj:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.1</TargetFramework>
      </PropertyGroup>
    
    </Project>
    

    The project file specifies everything that's needed to restore dependencies and build the program.

    • The OutputType tag specifies that we're building an executable, in other words a console application.
    • The TargetFramework tag specifies what .NET implementation we're targeting. In an advanced scenario, you can specify multiple target frameworks and build to all those in a single operation. In this tutorial, we'll stick to building only for .NET Core 1.0.

    Program.cs:

    using System;
    
    namespace Hello
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
            }
        }
    }
    

    The program starts by using System, which means "bring everything in the System namespace into scope for this file". The System namespace includes basic constructs such as string, or numeric types.

    We then define a namespace called Hello. You can change this to anything you want. A class named Program is defined within that namespace, with a Main method that takes an array of strings as its argument. This array contains the list of arguments passed in when the compiled program is called. As it is, this array is not used: all the program is doing is to write "Hello World!" to the console. Later, we'll make changes to the code that will make use of this argument.

    Note

    Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands that require a restore to occur, such as dotnet new, dotnet build and dotnet run. It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in Azure DevOps Services or in build systems that need to explicitly control the time at which the restore occurs.

    dotnet new calls dotnet restore implicitly. dotnet restore calls into NuGet (.NET package manager) to restore the tree of dependencies. NuGet analyzes the Hello.csproj file, downloads the dependencies defined in the file (or grabs them from a cache on your machine), and writes the obj/project.assets.json file, which is necessary to compile and run the sample.

    Important

    If you're using a .NET Core 1.x version of the SDK, you'll have to call dotnet restore yourself after calling dotnet new.

  2. $ dotnet run

    dotnet run calls dotnet build to ensure that the build targets have been built, and then calls dotnet <assembly.dll> to run the target application.

    $ dotnet run
    Hello World!
    

    Alternatively, you can also execute dotnet build to compile the code without running the build console applications. This results in a compiled application as a DLL file that can be run with dotnet bin\Debug\netcoreapp2.1\Hello.dll on Windows (use / for non-Windows systems). You may also specify arguments to the application as you'll see later on the topic.

    $ dotnet bin\Debug\netcoreapp2.1\Hello.dll
    Hello World!
    

    As an advanced scenario, it's possible to build the application as a self-contained set of platform-specific files that can be deployed and run to a machine that doesn't necessarily have .NET Core installed. See .NET Core Application Deployment for details.

Augmenting the program

Let's change the program a bit. Fibonacci numbers are fun, so let's add that in addition to use the argument to greet the person running the app.

  1. Replace the contents of your Program.cs file with the following code:

    using System;
    
    namespace Hello
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length > 0)
                {
                    Console.WriteLine($"Hello {args[0]}!");
                }
                else
                {
                    Console.WriteLine("Hello!");
                }
    
                Console.WriteLine("Fibonacci Numbers 1-15:");
    
                for (int i = 0; i < 15; i++)
                {
                    Console.WriteLine($"{i + 1}: {FibonacciNumber(i)}");
                }
            }
    
            static int FibonacciNumber(int n)
            {
                int a = 0;
                int b = 1;
                int tmp;
    
                for (int i = 0; i < n; i++)
                {
                    tmp = a;
                    a = b;
                    b += tmp;
                }
    
                return a;
            }
    
        }
    }
    
  2. Execute dotnet build to compile the changes.

  3. Run the program passing a parameter to the app:

    $ dotnet run -- John
    Hello John!
    Fibonacci Numbers 1-15:
    1: 0
    2: 1
    3: 1
    4: 2
    5: 3
    6: 5
    7: 8
    8: 13
    9: 21
    10: 34
    11: 55
    12: 89
    13: 144
    14: 233
    15: 377
    

And that's it! You can augment Program.cs any way you like.

Working with multiple files

Single files are fine for simple one-off programs, but if you're building a more complex app, you're probably going to have multiple source files on your project Let's build off of the previous Fibonacci example by caching some Fibonacci values and add some recursive features.

  1. Add a new file inside the Hello directory named FibonacciGenerator.cs with the following code:

    using System;
    using System.Collections.Generic;
    
    namespace Hello
    {
    	public class FibonacciGenerator
    	{
    		private Dictionary<int, int> _cache = new Dictionary<int, int>();
    		
    		private int Fib(int n) => n < 2 ? n : FibValue(n - 1) + FibValue(n - 2);
    		
    		private int FibValue(int n)
    		{
    			if (!_cache.ContainsKey(n))
    			{
    				_cache.Add(n, Fib(n));
    			}
    			
    			return _cache[n];
    		}
    		
    		public IEnumerable<int> Generate(int n)
    		{
    			for (int i = 0; i < n; i++)
    			{
    				yield return FibValue(i);
    			}
    		}
    	}
    }
    
  2. Change the Main method in your Program.cs file to instantiate the new class and call its method as in the following example:

    using System;
    
    namespace Hello
    {
        class Program
        {
            static void Main(string[] args)
            {
                var generator = new FibonacciGenerator();
                foreach (var digit in generator.Generate(15))
                {
                    Console.WriteLine(digit);
                }
            }
        }
    }
    
  3. Execute dotnet build to compile the changes.

  4. Run your app by executing dotnet run. The following shows the program output:

    $ dotnet run
    0
    1
    1
    2
    3
    5
    8
    13
    21
    34
    55
    89
    144
    233
    377
    

And that's it! Now, you can start using the basic concepts learned here to create your own programs.

Note that the commands and steps shown in this tutorial to run your application are used during development time only. Once you're ready to deploy your app, you'll want to take a look at the different deployment strategies for .NET Core apps and the dotnet publish command.

See also