Modern C# supports top-level statements, while traditional applications commonly place execution inside a Main() method. Statements usually end with semicolons and blocks use braces.
01 — Program Structure & Output
Basic Program
// Modern top-level statement
Console.WriteLine("Hello, world!");
// Traditional structure
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
}
}using System; makes common .NET types convenient to access. Main() is the traditional program entry point.
Console Output & Interpolation
Console.WriteLine("Hello"); // print + newline
Console.Write("Hello "); // print, no newline
string bird = "Heron";
int count = 3;
Console.WriteLine("I painted " + count + " " + bird + " paintings.");
Console.WriteLine($"I painted {count} {bird} paintings.");The $ prefix enables string interpolation. Expressions inside { } are inserted into the string.
C# is statically typed. Variables can state their type explicitly or use var when the compiler can infer the type from the initial value.
02 — Variables & Types
Declaration, Assignment & var
int quantity = 5;
int paintings;
paintings = 12;
paintings = 13;
var count = 5; // inferred as int
var name = "Susan"; // inferred as stringvar does not make a variable dynamically typed. Once inferred, its type remains fixed.
Common Built-In Types
byte smallNumber = 10;
short mediumNumber = 1000;
int number = 25;
long hugeNumber = 5000000000L;
float decimal1 = 3.14F;
double decimal2 = 3.14159;
decimal money = 29.95M;
char letter = 'A';
bool active = true;
string name = "Susan";int is the normal whole-number type. double is common for floating-point values. decimal is useful for decimal-sensitive calculations such as money and uses an M suffix. bool holds true or false.
Constants & readonly
const double TaxRate = 0.06625;
const int MaxStudents = 10;
class Example
{
private readonly string id;
public Example(string id)
{
this.id = id;
}
}const represents a compile-time constant. readonly fields can be assigned when declared or during construction, then cannot be freely reassigned.
C# uses familiar arithmetic, assignment, comparison, and Boolean operators. Strings provide properties and methods for common text operations.
03 — Operators & Strings
Arithmetic & Assignment
+ - * / %
score += 5;
score -= 5;
score *= 2;
score /= 2;
score++;
score--;Integer division drops the fractional remainder: 10 / 3 is 3. Decimal operands such as 10.0 / 3.0 produce a floating-point result.
Comparison & Boolean Logic
== != > < >= <=
&& // AND
|| // OR
! // NOT
if (age >= 18 && member)
{
Console.WriteLine("Access granted");
}= assigns a value. == tests equality.
String Properties, Methods & Equality
string animal = "Great Blue Heron";
Console.WriteLine(animal.Length);
Console.WriteLine(animal.ToUpper());
Console.WriteLine(animal.ToLower());
Console.WriteLine(animal.Contains("Heron"));
if (animal == "Great Blue Heron")
{
Console.WriteLine("Match");
}Length is a property, so it has no parentheses. C# overloads == for strings to compare their text values.
Arrays have fixed length. List<T> is a flexible generic collection. Conditions and loops control program execution.
04 — Arrays, Lists & Control Flow
Arrays & Lists
string[] birds = { "Heron", "Egret", "Pelican" };
Console.WriteLine(birds[0]);
Console.WriteLine(birds.Length);
List<string> birdList = new()
{
"Heron",
"Egret",
"Pelican"
};
birdList.Add("Osprey");
Console.WriteLine(birdList[0]);
Console.WriteLine(birdList.Count);Indexes begin at 0. Arrays use Length. Lists use Count.
if / else
if (paintings > 10)
{
Console.WriteLine("Large inventory");
}
else if (paintings > 5)
{
Console.WriteLine("Medium inventory");
}
else
{
Console.WriteLine("Low inventory");
}
for, foreach & while
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
foreach (string bird in birds)
{
Console.WriteLine(bird);
}
int count = 0;
while (count < 5)
{
Console.WriteLine(count);
count++;
}foreach is especially common for iterating arrays and collections.
switch
switch (status)
{
case "available":
Console.WriteLine("For sale");
break;
case "sold":
Console.WriteLine("Sold");
break;
default:
Console.WriteLine("Unknown");
break;
}
string message = status switch
{
"available" => "For sale",
"sold" => "Sold",
_ => "Unknown"
};The second form is a switch expression. _ acts as the fallback pattern.
Methods declare a return type and typed parameters. C# supports explicit casts, conversion helpers, parsing, and safe parsing.
05 — Methods & Conversion
Methods, void & Arguments
static int Add(int a, int b)
{
return a + b;
}
static void Greet(string name)
{
Console.WriteLine($"Hello {name}");
}
int answer = Add(5, 10);
Greet("Susan");Pattern: returnType MethodName(parameters). void means no value is returned. Values supplied during the call are arguments.
Casting, Convert, Parse & TryParse
double price = 29.95;
int wholePrice = (int)price;
string value = "25";
int a = Convert.ToInt32(value);
int b = int.Parse(value);
bool success = int.TryParse(value, out int number);An explicit cast such as (int) may discard information. TryParse is useful when input may be invalid because it reports success without requiring an exception for ordinary parse failure.
Classes define types. C# commonly exposes data through properties rather than public fields. Constructors and object initializers provide convenient ways to create objects.
06 — Classes, Properties & Objects
Class, Properties & Object
class Painting
{
public string Title { get; set; }
public decimal Price { get; set; }
public bool Sold { get; set; }
}
Painting painting = new();
painting.Title = "Blue Heron";
painting.Price = 125.00M;
painting.Sold = false;{ get; set; } defines an automatically implemented property that can be read and changed.
Constructors & Object Initializers
class Painting
{
public string Title { get; set; }
public decimal Price { get; set; }
public Painting(string title, decimal price)
{
Title = title;
Price = price;
}
}
Painting first = new Painting("Blue Heron", 125.00M);
// Object initializer style
Painting second = new()
{
Title = "Egret",
Price = 95.00M
};
Access Modifiers
public class Painting
{
private decimal price;
protected string category;
internal bool IsLoaded;
}public = broadly accessible. private = within the containing type. protected = containing type and derived types. internal = within the same assembly.
Modern C# provides nullable annotations and concise null-handling operators. Standard naming conventions make C# code visually distinctive.
07 — Nulls, Conventions & Memory Card
Nullable References & Null Operators
string? name = null;
if (name != null)
{
Console.WriteLine(name.Length);
}
Console.WriteLine(name?.Length);
string displayName = name ?? "Unknown";? can mark a reference as nullable. ?. performs null-conditional access. ?? supplies a fallback when the left side is null.
Core Memory Card
// VARIABLES
int count = 10;
decimal price = 12.50M;
bool active = true;
char grade = 'A';
string name = "Susan";
var quantity = 5;
// PRINT + INTERPOLATION
Console.WriteLine(name);
Console.WriteLine($"Hello {name}");
// CONDITION
if (count > 5)
{
Console.WriteLine("Yes");
}
// ARRAY + FOREACH
string[] birds = { "Heron", "Egret" };
foreach (string bird in birds)
{
Console.WriteLine(bird);
}
// LIST
List<string> birdList = new();
// METHOD
static int Add(int a, int b)
{
return a + b;
}
// PROPERTY
public string Title { get; set; }
// OBJECT
Painting painting = new();Five patterns: TYPE name = value; · Console.WriteLine(...); · if (condition) { ... } · foreach (TYPE item in collection) { ... } · returnType MethodName(parameters) { ... }
Comments & Naming