LyraLearn AI Learning Platform
Exams
← Module 2 Β· C# and Runtime Questions
🎧 Listen

LINQ, Delegates, and Interfaces

This cluster produces the single most frequently tested point in .NET interviews β€” deferred execution β€” plus two evergreen "compare these" questions. All three reward the clarify-then-answer habit.

The classic question: deferred execution

"This query runs, but the log shows the database was hit three times. Why?"

var flagged = transcripts.Where(t => t.NeedsReview);
if (flagged.Any()) log.Info($"{flagged.Count()} flagged");
return flagged.ToList();

The strong answer names the mechanism first: a LINQ query is a description, not a result β€” it executes each time it's enumerated. Any(), Count(), and ToList() are three enumerations, so against IQueryable that's three round trips (and against in-memory data, three re-computations β€” worse if the source changed in between). Fix: materialize once (ToList() early), then ask the list. Bonus depth: Count() > 0 on a query is itself a smell β€” Any() can stop at the first row.

Common follow-up: "Is deferred execution bad, then?" No β€” it's what lets EF compose Where clauses into one SQL statement before anything runs. The skill is knowing where the boundary is: compose lazily, materialize deliberately, never enumerate twice by accident.

IEnumerable vs IQueryable

Headline: both are lazy; the difference is where the work happens. IQueryable carries an expression tree that a provider (EF Core) translates to SQL β€” filtering happens in the database. IEnumerable runs compiled delegates in memory. The scenario version: "A search page got slow after a refactor that changed a repository return type" β€” someone returned IEnumerable, so Where now pulls the whole table into memory and filters there. Naming that exact failure, and the verify step ("I'd check the generated SQL"), is a pass.

Delegates, events, and the interface question

"What's a delegate?" A type-safe reference to a method β€” Func<Transcript, bool> is what every lambda you pass to LINQ actually is. Events are delegates with a safety contract: outsiders can only subscribe/unsubscribe, not invoke or overwrite the list. One sentence of depth: a subscriber that never unsubscribes keeps the publisher's reference alive β€” a classic managed memory leak.

"Interface vs abstract class?" Answer it as a modeling choice, not a feature list: an interface is a capability contract ("can be reviewed"), an abstract class is a shared identity with shared implementation ("is a document, with common base behavior"). A type gets one base class but many interfaces; interfaces are what you mock in tests and inject via DI β€” which is why modern ASP.NET Core code is interface-heavy. Mentioning that interfaces can now carry default implementations, and that this narrowed but didn't erase the distinction, is the up-to-date flourish.

Practice prompts:

  1. Explain deferred execution using a query you actually wrote, including the exact line where execution happens.
  2. "When would you deliberately return IEnumerable from a repository?" β€” defend it.
  3. Design aloud: reviewers need pluggable transcript-flagging rules. Interface, delegate, or abstract class β€” and why?
🧠 Quiz yourself on this lesson →

Ask the AI Tutor

Grounded in the course lessons β€” it cites its sources and says when it doesn't know.