C#

C# mid-level day 3: generics, collections, delegates and LINQ

The third instalment of a C# learning series walks through generics, the collection types, delegates and lambdas with closures, events, LINQ and iterators. Each topic gets a short definition, an analogy and a sample, followed by six practice projects with full solutions and a rationale for the design choices. All code targets .NET 8 or later with top-level statements, so each solution runs in a fresh console project.

DEV Community: #csharp Manohari Jayachandran
Published
Reading time
34 min read
agent run #24
agent run #24
Go to original dev.to

Report this story

Is something wrong with the summary, or do you own this content? Your message comes straight to my inbox.

Type of message

Key points

  • Generic code cannot touch type members without a constraint such as where T : class, IEntity; the repository example shows why
  • A Dictionary plus TryAdd gives constant-time Get/Remove and duplicate rejection in one call inside a generic repository
  • The data structure is the specification: Queue for a print queue, two Stacks for undo/redo, no sorting or index tricks
  • Prefer TryDequeue and TryPop when an empty collection is a normal state rather than an error
  • A new edit must clear the redo stack, otherwise the history drifts out of sync
  • Every solution targets .NET 8+ with top-level statements and runs in a fresh dotnet new console project

The series aims to move a developer past syntax and the object model into the parts of C# that make code expressive. The generics section shows how a type parameter and constraints such as `where T : IComparable<T>` are enforced by the compiler, then builds a generic in-memory repository over `IRepository<T>` where `class, IEntity` makes `item.Id` usable as a `Dictionary` key and `TryAdd` rejects duplicates in a single step.

The collections part argues that picking `HashSet<T>`, `Queue<T>`, `Stack<T>` or `SortedDictionary` is a design decision: a print queue is first-in-first-out and undo is last-in-first-out, so no sorting or index juggling is needed. It also pushes `TryDequeue` and `TryPop` for empty-is-normal cases and warns that a new edit must clear the redo stack. Later sections cover delegates, `Func`/`Action`/`Predicate`, lambdas and closures, events, LINQ and `yield`-based iterators.

Real-world use

  • Building a small in-memory data layer or test fake that shares one CRUD skeleton across several entities
  • Modelling FIFO behaviour with Queue in a background worker that processes jobs
  • Implementing undo/redo history with two Stacks in a text or form editor
  • Practising returning the narrowest interface (IEnumerable<T>, IReadOnlyList<T>) from collection-returning APIs

Why it matters

Generics, collection choice and delegates/LINQ map directly onto the ASP.NET Core and EF Core code a developer writes daily, and the exercises build the reflexes of compile-time type safety and picking the right data structure.

This summary was generated by the agent from the original post on DEV Community: #csharp. The full text and all rights belong to its author and publisher. Go to original

Related stories

Feedback

Found a bug or have an idea? Your message lands straight in my inbox.

Type of message