Master dictionaries, file operations, and event-driven programming in C#.
Learn key-value collections, file operations, and delegates/events.
Dictionary<TKey, TValue> to store and retrieve data using key-value pairs.using System.Collections.Generic;
// Create empty dictionary
Dictionary<string, int> ages = new Dictionary<string, int>();
// Or initialize with values
Dictionary<string, int> ages = new Dictionary<string, int>
{
{ "Alice", 25 },
{ "Bob", 30 },
{ "Charlie", 35 }
};// Add new entry
ages["Diana"] = 28;
ages.Add("Eve", 22); // Throws if key exists
// Access by key
int aliceAge = ages["Alice"]; // 25
// Safe access with TryGetValue
if (ages.TryGetValue("Frank", out int frankAge))
{
Console.WriteLine($"Frank is {frankAge}");
}
else
{
Console.WriteLine("Frank not found");
}// Check if key exists
bool hasAlice = ages.ContainsKey("Alice"); // true
bool has25 = ages.ContainsValue(25); // true
// Remove entry
ages.Remove("Bob");
// Get count
int count = ages.Count;// Iterate key-value pairs
foreach (KeyValuePair<string, int> kvp in ages)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// Or use var for cleaner syntax
foreach (var (name, age) in ages)
{
Console.WriteLine($"{name} is {age} years old");
}
// Iterate just keys or values
foreach (string name in ages.Keys) { }
foreach (int age in ages.Values) { }TryGetValue instead of checking ContainsKey then accessingSortedDictionary keeps keys in sorted orderConcurrentDictionarynew Dictionary<K,V>(100)Alice: 25
Bob: 30
Charlie: 35
Diana: 28
Count: 4
Contains Alice: True
Bob's age: 30
Dictionary<string, int> dict = new Dictionary<string, int>();dict["key"] = value; or dict.Add("key", value);int val = dict["key"];dict.ContainsKey("key")foreach (var kvp in dict) { }Review feedback below
System.IO classes.using System.IO;
// Write all text at once (creates or overwrites)
File.WriteAllText("output.txt", "Hello, World!");
// Write multiple lines
string[] lines = { "Line 1", "Line 2", "Line 3" };
File.WriteAllLines("output.txt", lines);
// Append to existing file
File.AppendAllText("output.txt", "\nAppended text");// Read entire file as string
string content = File.ReadAllText("input.txt");
Console.WriteLine(content);
// Read as array of lines
string[] lines = File.ReadAllLines("input.txt");
foreach (string line in lines)
{
Console.WriteLine(line);
}if (File.Exists("myfile.txt"))
{
Console.WriteLine("File exists!");
string content = File.ReadAllText("myfile.txt");
}
else
{
Console.WriteLine("File not found.");
}// Create directory
Directory.CreateDirectory("MyFolder");
// Check if directory exists
if (Directory.Exists("MyFolder"))
{
// Get all files in directory
string[] files = Directory.GetFiles("MyFolder");
foreach (string file in files)
{
Console.WriteLine(file);
}
}// Writing with StreamWriter
using (StreamWriter writer = new StreamWriter("log.txt"))
{
writer.WriteLine("Log entry 1");
writer.WriteLine("Log entry 2");
}
// Reading with StreamReader
using (StreamReader reader = new StreamReader("log.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}using statements for streams (auto-disposes)Path.Combine() for cross-platform pathsIOException and FileNotFoundExceptionFile.ReadAllTextAsync() for async operationsFileInfo for file metadata (size, dates, etc.)Writing to file...
File written successfully!
Reading from file:
Hello from C#!
This is line 2.
This is line 3.
File exists: True
File.WriteAllText("file.txt", "content");string content = File.ReadAllText("file.txt");if (File.Exists("file.txt")) { }using (StreamWriter sw = new StreamWriter("f.txt")) { }using System.IO; at the topReview feedback below
// Declare a delegate type
delegate void MessageHandler(string message);
// Create methods matching the signature
static void PrintMessage(string msg)
{
Console.WriteLine($"Message: {msg}");
}
static void LogMessage(string msg)
{
Console.WriteLine($"[LOG] {msg}");
}
// Use the delegate
MessageHandler handler = PrintMessage;
handler("Hello!"); // Output: Message: Hello!
// Multicast delegate (multiple methods)
handler += LogMessage;
handler("Test"); // Calls both methods!// Action: void return, 0-16 parameters
Action<string> print = msg => Console.WriteLine(msg);
print("Hello");
// Func: has return value (last type param)
Func<int, int, int> add = (a, b) => a + b;
int result = add(5, 3); // 8
// Predicate: returns bool
Predicate<int> isEven = n => n % 2 == 0;
bool even = isEven(4); // trueclass Button
{
// Declare event using EventHandler delegate
public event EventHandler Clicked;
// Method to raise the event
public void OnClick()
{
Console.WriteLine("Button clicked!");
Clicked?.Invoke(this, EventArgs.Empty);
}
}
// Subscribe to event
Button btn = new Button();
btn.Clicked += (sender, e) => Console.WriteLine("Handler 1 called");
btn.Clicked += (sender, e) => Console.WriteLine("Handler 2 called");
btn.OnClick(); // Triggers all handlersclass MessageEventArgs : EventArgs
{
public string Message { get; set; }
}
class Publisher
{
public event EventHandler<MessageEventArgs> MessageReceived;
public void SendMessage(string msg)
{
MessageReceived?.Invoke(this, new MessageEventArgs { Message = msg });
}
}Action and Func instead of custom delegates when possible?.Invoke() to safely raise events (null check)-= to unsubscribe from events (prevent memory leaks)Using delegate:
Message: Hello from delegate!
[LOG] Hello from delegate!
Using Action and Func:
Sum: 8
Button event:
Button clicked!
Handler executed!
delegate void Handler(string msg);Handler h = MyMethod;Action<string> a = s => Console.WriteLine(s);Func<int, int> f = x => x * 2;public event EventHandler MyEvent;Review feedback below