Let’s dive into C# by doing what developers do best—writing code. As you go through this article, don’t worry if something doesn’t click right away. C# is a big language, but it’s also one of the most intuitive and expressive once you get used to its flow.
We’ll start with basic syntax, then gradually bring in structure, logic, objects, and some modern tools that make your code cleaner and more powerful.
Starting Simple: Hello World and Running Code
In C#, every application starts somewhere—usually in a method called Main()
. But with newer versions of the language, you don’t even need to write that. Here's the simplest valid C# program:
Console.WriteLine("Hello, world!");
That line prints text to the console. You can copy that into a file, compile it with the .NET
CLI, and run it. This is a top-level statement—you don’t need to declare a class or a method to get started. Just write what you need, and C# handles the setup behind the scenes.
Declaring Variables and Understanding Types
Let’s add some data to our program. Variables hold values. In C#, every variable has a type, which tells the compiler what kind of data it stores—like text, numbers, or true/false flags.
int age = 30;
string name = "Alex";
bool isRegistered = true;
double score = 95.5;
char grade = 'A';
The var
keyword lets the compiler figure out the type for you:
var city = "New York"; // city is a string
var temperature = 72.5; // temperature is a double
Once a variable has a type, it can’t be changed. You can’t store a string in a variable that was created for integers. That’s one way C# helps catch bugs early.
Making Decisions: If Statements and Conditions
Real-world programs need logic. You want your app to do different things based on the values it has.
if (age >= 18)
{
Console.WriteLine("You're an adult.");
}
else
{
Console.WriteLine("You're a minor.");
}
That’s an if
statement. If the condition in parentheses is true, the first block runs. If not, it falls back to the else
.
There’s also the switch
expression, which is more readable when you’re checking a value against several cases:
string mood = "happy";
string message = mood switch
{
"happy" => "Great to hear!",
"sad" => "Hope things get better.",
_ => "Mood unclear."
};
Console.WriteLine(message);
Doing Things Repeatedly: Loops
C# gives you several ways to repeat actions. A for
loop is great when you know how many times you want to loop:
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"Number: {i}");
}
A while
loop keeps running as long as a condition is true:
int count = 3;
while (count > 0)
{
Console.WriteLine($"Countdown: {count}");
count--;
}
Breaking Down Logic into Methods
As your programs grow, you’ll want to break them into smaller pieces. Methods help you organize your code into reusable chunks.
static void SayHello(string name)
{
Console.WriteLine($"Hello, {name}!");
}
You call the method like this:
SayHello("Jamie");
You can also return values from methods:
static int Add(int a, int b)
{
return a + b;
}
Now you can call Add(3, 4)
and get back 7
.
Creating Your Own Types with Classes
C# is an object-oriented language, which means you can group data and behavior into classes. Here’s a basic class:
class Person
{
public string Name;
public int Age;
public void Introduce()
{
Console.WriteLine($"Hi, I’m {Name} and I’m {Age} years old.");
}
}
You create a new person like this:
var p = new Person();
p.Name = "Sam";
p.Age = 28;
p.Introduce();
You’ll often use properties instead of public fields so you can control access:
class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
That lets you use clean syntax like:
var item = new Product { Name = "Laptop", Price = 1299.99m };
Working with Lists and Filtering Data
Let’s say you have a bunch of numbers and you want to pick out the even ones. You can use a List<int>
and a LINQ query:
var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
var evens = numbers.Where(n => n % 2 == 0);
foreach (var n in evens)
{
Console.WriteLine(n);
}
LINQ is a powerful feature that makes querying data feel natural. You’ll use it a lot once you start working with collections, files, or databases.
Writing Asynchronous Code
Sometimes, your program has to wait—like when it’s downloading something. You don’t want it to freeze while it waits. That’s where async
and await
come in.
using System.Net.Http;
async Task FetchWebsite()
{
var client = new HttpClient();
string content = await client.GetStringAsync("https://example.com");
Console.WriteLine(content);
}
Calling await
pauses that method until the download finishes—but it doesn’t block the whole program.
A Taste of Modern C# Features
The C# language keeps evolving, and some newer features make your code cleaner and more expressive.
Records are great when you want to store data without worrying about writing constructors, equality checks, etc.
public record User(string Name, int Age);
You can copy and modify records easily:
var user1 = new User("Lena", 27);
var user2 = user1 with { Age = 28 };
Pattern matching lets you check types and values with elegant syntax:
object input = 42;
if (input is int number and > 10)
{
Console.WriteLine($"Large number: {number}");
}
What’s New in C# 14
With C# 14, some quality-of-life features were added that continue the language’s trend toward simplicity and safety.
Field-Backed Properties with field
You can now access the backing field of an auto-property using field
in the setter, which is super handy when adding validation.
public string Title
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
Null-Conditional Assignment on the Left-Hand Side
Now you can safely assign values even when the object might be null
:
customer?.Name = "New Name";
If customer
is null
, the assignment is just skipped—no exception thrown.
nameof
Works with Unbound Generics
You can now do this:
Console.WriteLine(nameof(List<>)); // Output: "List"
Parameter Modifiers in Lambdas
Lambdas now support modifiers like out
, ref
, and in
:
delegate bool TryParse<T>(string text, out T result);
TryParse<int> parse = (string s, out int result) => int.TryParse(s, out result);
Span and Memory Improvements
Conversions between arrays and Span<T>
or ReadOnlySpan<T>
are now easier, improving performance in high-speed scenarios like processing text or byte buffers.
Partial Constructors and Events
C# 14 allows constructors and events to be declared as partial
, so they can be split across files—a nice touch for large codebases or generated code.
Wrapping Up
You’ve just taken a solid tour through the core of C# programming—from the basics all the way to the cutting edge in C# 14. Now that you've got the tools, it’s time to start building.
You might want to try:
- A to-do list console app
- A mini text-based game
- A REST API with ASP.NET Core
- A Blazor UI project (yes, full front-end in C#!)
Conclusion
Learning C# is like learning a language that's designed to help you think clearly and build confidence. You’ve now seen how C# supports you from the ground up—with readable syntax, structured logic, object-oriented power, and a steady stream of modern features that make your life as a developer easier.
From writing your first Console.WriteLine
, to organizing your code into classes, filtering data with LINQ, and exploring async code and records—you've walked through the building blocks that power real-world applications. With C# 14, the language becomes even more expressive, letting you write safer, smarter, and more maintainable code.
Now it’s time to apply what you’ve learned. Pick a small project, experiment with what you’ve seen, and don’t worry about making it perfect. Programming is a process of iteration and discovery, and you’re well on your way.
If you’re ready to take the next step—whether that’s building a full app, exploring web development with ASP.NET, or diving into game development with Unity—C# has the tools, the ecosystem, and the community to support you.
Keep building. Keep learning. You’ve got this.