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
183: LinkedList<T>
I was working on a music playlist feature the other day and I initially reached for the standard List<T>. It's the default for a reason—it's fast and familiar. But then I realized the user wanted to be able to drag and drop songs to reorder them, or inject "Recommended" tracks right in the middle of a 5,000-song queue. That's when I stopped and remembered why LinkedList<T> exists.
The hidden cost of the standard List
If you use a List<string> for a playlist, it's backed by an array. When you call Insert(0, "New Song"), C# doesn't just "make room" at the front. It has to physically shift every single existing element one slot to the right in memory. With a few songs, you'll never notice. With thousands? You're wasting CPU cycles on memory copying.
// The "slow" way for large lists
var playlist = new List<string> { "Song A", "Song B", "Song C" };
playlist.Insert(0, "Intro Track"); // Everything shifts right. O(n) complexity.
I wanted something where I could just "snap" a new item into place without bothering the rest of the collection. That's where the doubly linked list comes in.
Trying out the LinkedList
I swapped my List for a LinkedList<string>. At first glance, it felt... different. I tried to access the third song using an index, and the compiler immediately shut me down.
var playlist = new LinkedList<string> { "Song A", "Song B", "Song C" };
// var thirdSong = playlist[2]; // Error! LinkedList doesn't support indexers.
This was my "aha!" moment. A LinkedList isn't a block of contiguous memory; it's a series of LinkedListNode<T> objects scattered around the heap, each holding a reference to the one before it and the one after it. You can't jump to index 2 because the list doesn't know where index 2 is until it starts at the head and follows the "next" pointers.
Navigating via Nodes
To actually manipulate the list, I realized I need to get a handle on a specific node. Since I can't use an index, I used the Find() method to locate a specific song and then used that node as a landmark for insertion.
var playlist = new LinkedList<string> { "Song A", "Song B", "Song C" };
// I want to put "Interlude" right after "Song A"
LinkedListNode<string> targetNode = playlist.Find("Song A");
if (targetNode != null)
{
playlist.AddAfter(targetNode, "Interlude");
}
// Now the list is: Song A -> Interlude -> Song B -> Song C
This is where the magic happens. Adding "Interlude" didn't require moving "Song B" or "Song C" in memory. C# just updated the Next pointer of "Song A" and the Previous pointer of "Song B" to point to the new node. It's an O(1) operation—constant time, regardless of whether the list has ten songs or ten million.
When to actually use this
You might be thinking, "Why bother with nodes if I can't just use list[i]?" You're right to be skeptical. If your primary goal is reading data randomly, LinkedList is a nightmare because you're always iterating from the start or end.
But if you're building something like a browser history (where you move back and forth), a music queue (where you insert/remove frequently), or a custom undo/redo stack, the LinkedList<T> is your best friend. I use it whenever the "cost of shifting" in a standard list outweighs the "cost of searching" for a node.
📋 Practical Task
The Dynamic Playlist Reorderer
Build a small console application that simulates a music playlist using LinkedList<string>. Your program should perform the following sequence of operations:
- Initialize a
LinkedList<string>with three songs: "Bohemian Rhapsody", "Stairway to Heaven", and "Hotel California". - Use the
AddFirst()method to add "Intro Theme" to the very beginning of the list. - Use the
AddLast()method to add "Outro Credits" to the end of the list. - Find the node containing "Stairway to Heaven" and use
AddAfter()to insert "Imagine" immediately following it. - Find the node containing "Hotel California" and use
Remove()to delete it from the playlist. - Finally, use a
foreachloop to print the final order of the playlist to the console to verify the changes.
There are no comments for now.