Your First C# Program

C# · Lesson 3 of 31 8 min read Updated

In the last lesson you created a project and saw Hello, World!. Now you will open that project, understand every file in it, change the program, and learn the two ways to run C# in .NET 10: as a normal project and as a single file-based app.

You will also learn to read the compiler's error messages, which is one of the most useful skills a beginner can have.

Inside a console project

Run dotnet new console -o HelloRohtak (or reuse the project from last lesson) and look at the folder:

Text
HelloRohtak/
  HelloRohtak.csproj
  Program.cs
  obj/
  • Program.cs holds your C# code.
  • HelloRohtak.csproj is the project file. It tells the SDK how to build the program.
  • obj/ and, after the first build, bin/ hold temporary and compiled files. You never edit them, and you do not commit them to Git.

Open the project file. It is short:

XML
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>
  • OutputType Exe means this project produces a program you can run, not a library.
  • TargetFramework net10.0 means it runs on .NET 10, which also selects C# 14.
  • ImplicitUsings adds common using lines for you, so Console, List and File work without extra imports.
  • Nullable turns on warnings that help you avoid null errors. You will learn this in Nullable Types & Null Safety.

Top-level statements

Now open Program.cs. The template contains just two lines:

C#
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

The first line is a comment: the compiler ignores everything after //. The second line is a statement: an instruction that ends with a semicolon. Console is a class from the base class library, and WriteLine is a method that prints text followed by a new line.

These lines are called top-level statements: code written directly in the file, not inside a class or method. The compiler wraps them in a hidden class with a Main method, the starting point of the program. Statements run from top to bottom.

Replace the contents of Program.cs with your own program:

C#
Console.WriteLine("Welcome to Rohtak Cricket Academy");
Console.Write("Coach: ");
Console.WriteLine("Kabir Singh");
Console.WriteLine();
Console.WriteLine("Nets start at 6:30 AM.");

Run it with dotnet run:

Output
Welcome to Rohtak Cricket Academy
Coach: Kabir Singh

Nets start at 6:30 AM.

Console.Write prints without moving to a new line, so Kabir Singh appears on the same line as Coach: . An empty Console.WriteLine() prints a blank line.

Build and run separately

dotnet run does two jobs: it builds (compiles) the project and then runs it. You can also do them one at a time:

Terminal
dotnet build
dotnet bin/Debug/net10.0/HelloRohtak.dll

dotnet build writes the compiled program to bin/Debug/net10.0/. The .dll file contains IL code, and dotnet HelloRohtak.dll starts the runtime and runs it. On Windows the build also creates HelloRohtak.exe, a small launcher you can double-click or run directly.

Debug is the default build configuration: easy to debug, not fully optimised. When you are ready to share a program, dotnet publish -c Release creates an optimised version.

File-based apps: dotnet run app.cs

Create a file tip.cs anywhere (not inside a project folder) with this code:

C#
int bill = 1240;
int people = 4;
Console.WriteLine($"Total bill: Rs {bill}");
Console.WriteLine($"Each of the {people} friends pays Rs {bill / people}");

Run it:

Terminal
dotnet run tip.cs
Output
Total bill: Rs 1240
Each of the 4 friends pays Rs 310

File-based apps are perfect for practice, small scripts and quick experiments. A file can configure itself with special #: lines at the very top. For example, #:package adds a NuGet package (a downloadable library) and #:property sets a build setting:

C#
#:package Humanizer@2.14.1
#:property Nullable=enable

using Humanizer;

Console.WriteLine("nagpur express".Titleize());

The first run downloads the package; after that, the program can use the package's Titleize method, which capitalises each word.

When a script grows into a real application, convert it into a normal project:

Terminal
dotnet project convert tip.cs

This creates a new folder containing a .csproj and a copy of your file, and leaves the original untouched. Many examples in this course are short enough to run as file-based apps. Larger examples, such as web APIs and tests, need a project.

Reading compiler errors

Mistakes are normal. What matters is reading the error message calmly. Suppose you forget a semicolon and write console in lower case:

C#
Console.WriteLine("Fees due: Rs 1500")
console.WriteLine("Pay at the office");

dotnet build reports both problems:

Output
Program.cs(1,39): error CS1002: ; expected
Program.cs(2,1): error CS0103: The name 'console' does not exist in the current context

Each error tells you the file, the line and column in brackets, an error code such as CS1002, and a message. Line 1, column 39 is exactly where the missing semicolon should be. The second error happens because C# is case-sensitive: Console and console are different names. You can search for any error code on learn.microsoft.com to read a full explanation.

Common mistakes

  • Wrong capital letters. console.writeline fails; it must be Console.WriteLine.
  • Missing semicolons. Every statement ends with ;. Error CS1002 points to the spot.
  • Top-level statements in two files. Only one file in a project may contain them, otherwise you get error CS8802. Put other code in classes.
  • dotnet run app.cs inside a project folder. If the current folder already has a .csproj, the SDK runs that project instead. Keep scripts in a separate folder, or use dotnet run --file app.cs.
  • Editing files in bin or obj. They are rebuilt every time; your changes disappear.

Key points

  • A console project has a .csproj project file and a Program.cs code file.
  • Top-level statements are code written directly in Program.cs; the compiler wraps them in a hidden Main method.
  • Console.WriteLine prints a line; Console.Write prints without a line break.
  • dotnet run builds and runs; dotnet build only compiles into bin/Debug/net10.0/.
  • .NET 10 can run a single file with dotnet run app.cs, configured with #:package and #:property lines.
  • Compiler errors give the file, line, column, a CS code and a message.

Exercise

Create a file-based app called ticket.cs that prints a train ticket like this, using one Console.Write and several Console.WriteLine calls. Then deliberately remove one semicolon, run it again, and note which line and column the error reports.

Output
INDIAN RAILWAYS
Train: 12015 Ajmer Shatabdi
From: New Delhi
To: Jaipur

Passenger: Isha Verma
Show solution
C#
Console.WriteLine("INDIAN RAILWAYS");
Console.WriteLine("Train: 12015 Ajmer Shatabdi");
Console.WriteLine("From: New Delhi");
Console.WriteLine("To: Jaipur");
Console.WriteLine();
Console.Write("Passenger: ");
Console.WriteLine("Isha Verma");

Run it with dotnet run ticket.cs. The empty Console.WriteLine() makes the blank line, and Console.Write keeps the name on the same line as Passenger: . Removing a semicolon gives error CS1002: ; expected with the line and column of the missing ;.

Quick Quiz

1. What are top-level statements?

2. What is the difference between Console.Write and Console.WriteLine?

3. Which command runs a single C# file without a project in .NET 10?

4. An error says Program.cs(2,1): error CS0103: The name 'console' does not exist in the current context. What is the likely fix?

Learn C# with a mentor

Free lessons get you started. Our Programming & Software Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call