Declaring Variables with Built-in Types
In a console app, most programs follow a simple loop: read text from the user, convert it into useful data, compute something, then print results. To compute, you store values in variables. A variable has a type (what kind of data it can hold) and a name (how you refer to it).
Common built-in types
- int: whole numbers (e.g., 0, 42, -10)
- double: decimal numbers (e.g., 3.14, -0.5)
- bool: true/false
- char: a single character (e.g., 'A', '7')
- string: text (e.g., "Hello")
Examples of declaring and using them:
int age = 25; double price = 19.99; bool isMember = true; char grade = 'A'; string name = "Sam"; Console.WriteLine($"{name} is {age} years old, grade {grade}, member: {isMember}, price: {price}");Notice the string interpolation syntax: $"...{variable}...". It is the most readable way to format console output.
Type Inference with var
Sometimes the type is obvious from the right-hand side. You can let the compiler infer it using var. The variable still has a static type; you just don’t write it explicitly.
var count = 10; // inferred as int var rate = 0.075; // inferred as double var title = "Report"; // inferred as stringUse var when it improves readability (especially with long type names) and avoid it when it hides important information (for example, whether a number is int or double).
Continue in our app.
You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.
Or continue reading below...Download the app
Immutability with const
Use const for values that should never change while the program runs. This prevents accidental reassignment and makes intent clear.
const double TaxRate = 0.08; // 8% // TaxRate = 0.10; // compile-time errorconst values must be known at compile time (numbers, chars, strings, etc.).
Console I/O: Prompt, Read, and Print
Console apps typically use:
Console.Writeto prompt without a newlineConsole.WriteLineto print with a newlineConsole.ReadLineto read a full line of input as astring?
Console.Write("Enter your name: "); string? input = Console.ReadLine(); Console.WriteLine($"You typed: {input}");ReadLine returns a nullable string (string?) because it can return null in some scenarios (for example, redirected input reaching end-of-stream). You should handle that possibility in robust code.
Conversions: Turning User Input into Numbers
User input arrives as text, so you often need to convert strings to numeric types.
Parsing with int.Parse / double.Parse
Parse converts a string to a number, but it throws an exception if the format is invalid.
string text = "123"; int n = int.Parse(text);In interactive console apps, prefer TryParse to avoid exceptions and handle invalid input gracefully.
Safer parsing with TryParse
Console.Write("Enter an integer: "); string? raw = Console.ReadLine(); if (int.TryParse(raw, out int value)) { Console.WriteLine($"You entered {value}."); } else { Console.WriteLine("That was not a valid integer."); }TryParse returns true if conversion succeeded and stores the result in the out variable.
Lab 1: Greeting the User (string, trimming, interpolation)
This lab focuses on reading text, doing minimal validation, and printing a formatted result.
Steps
- Prompt for a name.
- Read input.
- Trim leading/trailing spaces.
- Reject empty input.
- Print a greeting using interpolation.
Console.Write("Enter your name: "); string? nameInput = Console.ReadLine(); string name = (nameInput ?? "").Trim(); if (name.Length == 0) { Console.WriteLine("Name cannot be empty."); } else { Console.WriteLine($"Hello, {name}!" ); }Key idea: treat null as an empty string using (nameInput ?? ""), then validate after trimming.
Lab 2: Age Next Year (int parsing + formatted output)
This lab converts user input into an int and uses it in a calculation.
Steps
- Prompt for age.
- Read input.
- Try to parse to
int. - Validate a reasonable range.
- Print the computed result.
Console.Write("Enter your age: "); string? rawAge = Console.ReadLine(); if (!int.TryParse(rawAge, out int age)) { Console.WriteLine("Please enter a whole number."); } else if (age < 0 || age > 130) { Console.WriteLine("Please enter an age between 0 and 130."); } else { int nextYear = age + 1; Console.WriteLine($"Next year you will be {nextYear}." ); }Notice the two layers of validation: format (can it be parsed?) and meaning (is it in a sensible range?).
Lab 3: Simple Receipt (double, const, and numeric formatting)
This lab uses double for a price, a const tax rate, and formatted output.
Steps
- Prompt for a subtotal.
- Parse to
double. - Compute tax and total.
- Print values with two decimal places.
const double TaxRate = 0.08; Console.Write("Enter subtotal: "); string? rawSubtotal = Console.ReadLine(); if (!double.TryParse(rawSubtotal, out double subtotal) || subtotal < 0) { Console.WriteLine("Enter a valid non-negative number."); } else { double tax = subtotal * TaxRate; double total = subtotal + tax; Console.WriteLine($"Subtotal: {subtotal:F2}"); Console.WriteLine($"Tax ({TaxRate:P0}): {tax:F2}"); Console.WriteLine($"Total: {total:F2}"); }Formatting tips: {value:F2} prints two decimal places; {TaxRate:P0} prints a percentage with zero decimals (0.08 becomes 8%).
Lab 4: Yes/No Input (bool and minimal normalization)
Users rarely type exactly what you expect. Normalize input before checking it.
Steps
- Prompt for a yes/no answer.
- Trim and convert to a consistent case.
- Map common variants to a
bool.
Console.Write("Are you a member? (y/n): "); string answer = ((Console.ReadLine() ?? "").Trim()).ToLowerInvariant(); bool isMember; if (answer == "y" || answer == "yes") { isMember = true; } else if (answer == "n" || answer == "no") { isMember = false; } else { Console.WriteLine("Please type y/n (or yes/no)." ); return; } Console.WriteLine($"Member status: {isMember}" );This pattern keeps the program predictable while accepting small variations in user input.
Focused Pitfalls and How to Avoid Them
Null vs empty vs whitespace strings
- null: no string object (possible from
ReadLine) - empty:
""(length 0) - whitespace:
" "(looks empty to humans)
Use string.IsNullOrWhiteSpace to catch all three cases in one check.
string? input = Console.ReadLine(); if (string.IsNullOrWhiteSpace(input)) { Console.WriteLine("Input is required."); }Numeric parsing failures
Common reasons parsing fails:
- User types letters or punctuation (
"12a","$10"). - User uses a different decimal separator depending on culture settings.
- User enters an empty line.
Prefer TryParse and respond with a clear prompt. If you need strict formatting (for example, always using a dot as decimal separator), you can parse with an explicit culture, but for many beginner console apps, TryParse plus a retry loop is enough.
Accidentally using the wrong numeric type
intcannot store decimals; parsing"3.5"intointfails.doublecan represent decimals but may introduce floating-point rounding (fine for many simple console exercises; be cautious for money).
Pick the type that matches the data: whole counts use int; measurements often use double.
Forgetting that var is not “dynamic”
var does not mean the variable can change types later. This will not compile:
var x = 10; // int // x = "ten"; // errorUse var for convenience, not to avoid thinking about types.
Assuming ReadLine always returns a value
In interactive use it usually does, but robust code treats it as nullable. A simple defensive pattern is:
string input = Console.ReadLine() ?? "";