Read the syntax
A declaration names a type, then a variable, and normally an initial value: int age = 21;. C# checks assignments against the variable’s type before the program runs; var asks the compiler to infer that type, not to make it dynamic.
Use a decimal literal with an m suffix for base-ten arithmetic, a single quoted character for char, and double quoted text for string. A ? on a value type permits null; ?? supplies a fallback when the value is null.
Syntax
type variableName = value;Breaking down the syntax
int- An integer type.
string- A text reference type.
var- Infers a local variable type from its initializer.
How it works
A C# local variable has a type that controls which values it can hold. var asks the compiler to infer that type from its initial value.
Declare
Choose a name and type, or infer it.
Assign
Supply a compatible value.
Use
Operations are checked against that type.
Examples
A small working example
Follow the values through this example, then change one input.
using System;
class Program {
static void Main() {
int lessons = 3;
string language = "C#";
Console.WriteLine($"{language}: {lessons} lessons");
}
}- lessons stores an int.
- language stores text.
- The interpolated string inserts both values.
Declaring Variables
Creating variables of common built-in types.
int age = 21;
double gpa = 3.8;
decimal price = 19.99m; // m suffix for decimal - ideal for money
char grade = 'A';
bool isStudent = true;
string name = "John";
Console.WriteLine($"{name}, {age}, {gpa}, {grade}, {isStudent}");- Creating variables of common built-in types.
- A declaration names a type, then a variable, and normally an initial value: int age = 21;. C# checks assignments against the variable’s type before the program runs; var asks the compiler to infer that type, not to make it dynamic.
- The six declarations hold different kinds of values. Interpolation inserts five of them into one console line; price is declared but is not printed. The m suffix makes 19.99 a decimal rather than a double.
Implicit Typing with var
The compiler infers the type from the right-hand side - the variable is still strongly typed, just without an explicit type name.
var count = 10; // inferred as int
var total = 19.99; // inferred as double
var label = "Total: "; // inferred as string
// count = "text"; // Error! count is still an int under the hood
Console.WriteLine(label + total);- The compiler infers the type from the right-hand side - the variable is still strongly typed, just without an explicit type name.
- A declaration names a type, then a variable, and normally an initial value: int age = 21;. C# checks assignments against the variable’s type before the program runs; var asks the compiler to infer that type, not to make it dynamic.
- count remains an int, so uncommenting the string assignment produces a compile-time error. The final line concatenates label and total and prints Total: 19.99 under a culture that uses a dot for decimals.
Constants with const and readonly
const values are fixed at compile time; readonly values can be set once, at declaration or in a constructor.
const double Pi = 3.14159; // must be assigned a compile-time constant
Console.WriteLine(Pi);
class Circle
{
public readonly double Radius; // can be set in the constructor, not after
public Circle(double radius)
{
Radius = radius;
}
}- const values are fixed at compile time; readonly values can be set once, at declaration or in a constructor.
- A declaration names a type, then a variable, and normally an initial value: int age = 21;. C# checks assignments against the variable’s type before the program runs; var asks the compiler to infer that type, not to make it dynamic.
- Pi can be printed because its value is known at compile time. Circle is only declared here: no Circle object is created, so Radius is never printed; its constructor can assign that readonly field.
Nullable Value Types
Value types like int normally can't be null - appending ? makes them nullable.
int? age = null; // nullable int
double? score = 85.5;
if (age.HasValue)
{
Console.WriteLine(age.Value);
}
else
{
Console.WriteLine("Age not set");
}
int actualAge = age ?? 0; // null-coalescing: use 0 if age is null
Console.WriteLine(actualAge);- Value types like int normally can't be null - appending ? makes them nullable.
- A declaration names a type, then a variable, and normally an initial value: int age = 21;. C# checks assignments against the variable’s type before the program runs; var asks the compiler to infer that type, not to make it dynamic.
- age.HasValue is false, so the else branch prints Age not set. The ?? expression then chooses 0 and prints it; accessing age.Value without the preceding check would throw.
Best practices
- Use PascalCase for public members and camelCase for local variables and private fields, following standard C# naming conventions
- Use var when the type is obvious from the right-hand side (var list = new List<string>();), but prefer an explicit type when it improves readability
- Use decimal, never double or float, for money and other values where exact precision matters - double introduces small rounding errors
- Use nullable value types (int?) and the null-coalescing operator (??) to handle "no value" cases explicitly, rather than relying on magic sentinel numbers
Runtime & versions
.NET runtime. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
C# language referenceWhen should I use this?
Name intermediate results and application state with types that communicate their meaning.
Common mistakes
A common trap
var inferred int; it does not make the variable dynamically typed.
Incorrect
var count = 1;
count = "two";Corrected
var count = 1;
count = 2;Compare approaches
- Explicit type: Make the type visible at the declaration.
- var: Use inference when the initializer makes the type clear.
Explore deeper
decimal literals
Use the m suffix for decimal literals, for example 12.50m. Decimal arithmetic is often useful for base-10 financial values; rounding rules still need an explicit application policy.