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
180: List<T> Members In Depth
By now, you're probably comfortable adding items to a list and looping through them. But if you look at the List<T> class in the documentation, there are dozens of methods you probably haven't touched yet. I've found that most developers stick to Add() and Remove() for far too long, missing out on tools that make the code cleaner and more performant.
What is the actual difference between Count and Capacity?
This is one of those things that doesn't matter until your app starts lagging. Count is the number of elements currently in your list. Capacity is the number of elements the internal array can hold before it needs to resize.
Here is the deal: List<T> is just a wrapper around a standard array. When that array fills up and you call Add(), C# has to allocate a new, larger array (usually double the size) and copy everything over. If you're adding 100,000 items to a list, that happens a lot, and it's expensive.
// If I know I'm loading 10,000 enemies from a save file...
var enemies = new List<Enemy>(10000);
// I just set the Capacity to 10,000 immediately.
// No resizing happens as I fill it up.
I usually only worry about this in performance-critical paths, but it's a great habit to set the capacity if you have a rough idea of the final size.
Why use FindAll instead of just writing a foreach loop?
You can definitely use a foreach loop and a temporary list to filter data, but FindAll lets you do it in one line using a predicate (a lambda expression). It's much more expressive.
Imagine we have a list of GameEnemy objects and we only want the ones that are currently "Elite" types. Instead of this:
var elites = new List<GameEnemy>();
foreach (var e in allEnemies) {
if (e.Type == EnemyType.Elite) elites.Add(e);
}
Do this:
var elites = allEnemies.FindAll(e => e.Type == EnemyType.Elite);
It's cleaner, it's faster to read, and it reduces the surface area for bugs. Similar logic applies to Find(), which just returns the first match it hits, or Exists(), which returns a simple true/false.
How do I remove multiple items without crashing the loop?
If you've tried to Remove() an item from a list while iterating over it with a foreach loop, you've probably seen the InvalidOperationException. C# doesn't let you modify the collection while you're walking through it.
The "old school" way to fix this was to loop backwards using a for loop, but that's clunky. The professional way to handle this is RemoveAll(). It takes a predicate and purges everything that matches it in one go.
// Let's say we want to clear out all enemies whose health has hit 0
allEnemies.RemoveAll(e => e.Health <= 0);
I love RemoveAll because it's atomic from your perspective. You don't have to manage indices or temporary "to-be-deleted" lists. It just happens.
📋 Practical Task
Exercise: Managing the Horde
You are building a combat manager for a game. You have a list of Enemy objects (each with a Name, Health, and IsBoss property). Your task is to implement the following logic using the List<T> members discussed in this lesson:
- Initialize a list with an initial capacity of 50.
- Use
FindAllto create a sub-list of all enemies that are Bosses. - Use
RemoveAllto instantly delete all enemies from the main list whose Health is 0 or less. - Use
Existsto check if there are any enemies left in the list and print "Area Clear" or "Enemies Remain" to the console.
Ensure you use lambda expressions for the predicates to keep your code concise.
There are no comments for now.