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
137: Building a Todo List with Persistence
Where do I actually save my list so it doesn't disappear when I close the app?
When you're building a small tool like a Todo list, the temptation is to jump straight into a database like SQL Server or MongoDB. Honestly? Don't do that yet. You'll spend more time configuring connection strings than writing actual logic. For this kind of project, a flat JSON file on your hard drive is perfect. It's human-readable, meaning you can open it in a text editor to verify your data is actually there, and it's more than fast enough for a few hundred tasks.
In C#, we use the System.IO namespace to talk to the file system. I usually define a private constant for the filename at the top of my class so I'm not hunting through the code to change "todos.json" to "tasks.json" later.
How do I turn my C# objects into a format a file can understand?
C# objects live in your RAM as complex structures; you can't just "dump" a List<TodoItem> into a text file and expect it to make sense. You need serialization. I always recommend System.Text.Json these days—it's built-in, high-performance, and doesn't require third-party NuGet packages for basic use.
public class TodoItem
{
public string Task { get; set; }
public bool IsCompleted { get; set; }
}
// Saving the list to disk
public void SaveTasks(List<TodoItem> tasks)
{
string jsonString = JsonSerializer.Serialize(tasks, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText("todos.json", jsonString);
}
The WriteIndented = true part is my personal preference. It makes the resulting JSON file look pretty with line breaks and spaces, which is a lifesaver when you're debugging. Without it, the whole list is just one giant, unreadable line of text.
Do I have to reload the file every time I add or check a task?
This is where a lot of people overcomplicate things. You don't want to read from the disk every single time you toggle a checkbox—that's incredibly inefficient. Instead, treat the file as your "long-term storage" and a local List<TodoItem> as your "working memory."
The workflow I use looks like this:
- On Startup: Check if the file exists. If it does, deserialize the JSON back into a C# list. If not, start with an empty list.
- During Runtime: All adds, deletes, and toggles happen to the list in memory.
- On Change: Call your save method to overwrite the file with the current state of the list.
You might worry that overwriting the whole file is wasteful, but for a Todo list, the file size is tiny. It's much simpler to just overwrite the whole thing than to try and surgically edit one line of JSON inside a text file.
📋 Practical Task
Implement a 'Priority' level with JSON persistence
It's time to put this into practice. I want you to expand the Todo list project by adding a Priority property to the TodoItem class. Use an enum for this (with values like Low, Medium, and High).
Your challenge is to ensure that the priority level is correctly saved to and loaded from your JSON file. Additionally, add a check during the loading process: if the todos.json file is missing or corrupted, your program should catch the exception and initialize a fresh, empty list instead of crashing. Test it by adding a "High Priority" task, restarting the app, and verifying the priority is still there.
There are no comments for now.