C#
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C#
-
Section 4: Working with Data
-
Section 5: Error Handling
-
Section 6: Delegates and Events
-
Section 7: Async Programming
-
Section 8: More Language Features
-
Section 9: File I/O and Serialization
-
Section 10: Networking in .NET
-
Section 11: The .NET Ecosystem
-
Section 12: Memory and Performance
-
Section 13: Concurrency Beyond Async
-
Section 14: Reflection and Attributes
-
Section 15: Testing and Best Practices
-
Section 16: Design Patterns in C#
-
Section 17: Standard Library Deep Dive
-
Section 18: Data Structures and Algorithms in C#
-
Section 19: GUI and Desktop Development Overview
-
Section 20: Practical Projects
-
Section 21: More Practice Exercises
-
Section 22: More Standard Library and Text Processing
-
Section 23: More Design Patterns
-
Section 24: More Projects
-
Section 25: Interview Practice
-
Section 26: C# Keywords Reference (Modifiers)
-
Section 27: C# Keywords Reference (Statements)
-
Section 28: C# Keywords Reference (Operators)
-
Section 29: BCL: System.Collections.Generic
-
Section 30: BCL: System.Linq
-
Section 31: BCL: System.Threading
-
Section 32: BCL: System.IO
-
Section 33: BCL: System.Text and System.Text.Json
-
Section 34: BCL: System.Net.Http
-
Section 35: C# Language Specification Topics
-
Section 36: More Practice Exercises
-
Section 37: More Async Patterns
-
Section 38: More BCL: System.Reflection and System.Diagnostics
-
Section 39: Nullable Reference Types In Depth
-
Section 40: C# Records and Pattern Matching In Depth
-
Section 41: Dependency Injection Deep Dive
-
Section 42: More Interview and Whiteboard Practice
182: Queue<T> and Stack<T>
Think about the last time you stood in line at a coffee shop. You walk in, join the back of the line, and wait. The person who arrived first gets their latte first, and the person who just walked through the door has to wait for everyone in front of them to be served. That's a Queue.
Now, imagine a stack of cafeteria trays. When the dishwasher puts a clean tray down, it goes on top of the pile. When you come along to grab a tray, you don't reach for the one at the very bottom—you take the one right off the top. The last tray placed on the stack is the first one taken off. That's a Stack.
Handling the Line with Queue<T>
In C#, a Queue<T> follows this "First-In, First-Out" (FIFO) logic. I use these all the time when I need to process tasks in the exact order they arrived without worrying about indexing into a list.
Let's map our coffee shop analogy to the code:
- Joining the line: We use
Enqueue()to add an item to the back. - Getting served: We use
Dequeue()to remove and return the item at the front. - Checking the next person:
Peek()lets us see who is next without actually removing them from the line.
using System;
using System.Collections.Generic;
var printJobs = new Queue<string>();
// Adding jobs to the printer (Enqueue)
printJobs.Enqueue("Quarterly_Report.pdf");
printJobs.Enqueue("Family_Photo.jpg");
printJobs.Enqueue("Resume_Final_v2.docx");
Console.WriteLine($"Next up to print: {printJobs.Peek()}"); // Quarterly_Report.pdf
while (printJobs.Count > 0)
{
string currentJob = printJobs.Dequeue();
Console.WriteLine($"Printing: {currentJob}...");
}
Piling Things Up with Stack<T>
A Stack<T> is the opposite: "Last-In, First-Out" (LIFO). If you've ever used the "Undo" feature in a text editor, you've used a stack. The editor keeps a stack of every change you make; when you hit Ctrl+Z, it "pops" the very last action you performed off the top of the stack to reverse it.
Here is how the tray analogy translates to C#:
- Adding to the top:
Push()puts a new item on top of the stack. - Taking from the top:
Pop()removes and returns the top item. - Looking at the top:
Peek()shows you the top item without removing it.
using System;
using System.Collections.Generic;
var undoStack = new Stack<string>();
// User performs actions
undoStack.Push("Typed 'Hello'");
undoStack.Push("Changed font to Bold");
undoStack.Push("Inserted Image");
Console.WriteLine($"Last action: {undoStack.Peek()}"); // Inserted Image
// User hits Ctrl+Z
string lastAction = undoStack.Pop();
Console.WriteLine($"Undoing: {lastAction}"); // Undoing: Inserted Image
Console.WriteLine($"Now the top action is: {undoStack.Peek()}"); // Changed font to Bold
Choosing the Right Tool for the Job
You might be wondering, "Why not just use a List<T> for everything?" You technically could, but I wouldn't recommend it. Using a Queue or a Stack tells other developers exactly how the data is intended to move. It's a signal. If I see a Stack in your code, I immediately know we're dealing with a "last-in, first-out" scenario. I don't have to hunt through your loops to figure out if you're adding or removing from the start or the end of a list.
One quick tip: be careful with Pop() and Dequeue(). If the collection is empty, C# will throw an InvalidOperationException. Always check the Count property or use the TryPop and TryDequeue methods if you aren't 100% sure there's something in there.
📋 Practical Task
Building a Simple Browser History Simulator
Your goal is to create a small console application that simulates how a web browser handles the "Back" button. A browser's history is a perfect use case for a Stack<T> because the last page you visited is the first one you return to when you go back.
Requirements:
- Create a
Stack<string>to store URLs. - Implement a way to "Visit" a page (add a URL to the stack). Visit at least three different websites (e.g., "google.com", "github.com", "stackoverflow.com").
- Implement a "Back" feature that removes the current page from the stack and displays the URL of the page the user has returned to.
- Ensure your code handles the case where the user tries to go "Back" when there are no more pages left in the history (prevent the app from crashing).
- Print the remaining history to the console at the end.
There are no comments for now.