Free Ebook cover C# Essentials: Building Console Apps with .NET

C# Essentials: Building Console Apps with .NET

New course

12 pages

C# Types, Variables, and Console I/O

Capítulo 3

Estimated reading time: 6 minutes

+ Exercise

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 string

Use 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 App

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 error

const values must be known at compile time (numbers, chars, strings, etc.).

Console I/O: Prompt, Read, and Print

Console apps typically use:

  • Console.Write to prompt without a newline
  • Console.WriteLine to print with a newline
  • Console.ReadLine to read a full line of input as a string?
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

  • int cannot store decimals; parsing "3.5" into int fails.
  • double can 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"; // error

Use 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() ?? "";

Now answer the exercise about the content:

In a console app, which approach best avoids exceptions when converting a user-entered age to an int while handling invalid input gracefully?

You are right! Congratulations, now go to the next page

You missed! Try again.

TryParse returns a bool to indicate success and writes the converted value to an out variable, letting you handle invalid input without throwing exceptions.

Next chapter

Operators and Expressions in C# Console Programs

Arrow Right Icon
Download the app to earn free Certification and listen to the courses in the background, even with the screen off.