Generics, delegates and events, LINQ, advanced and modern C# 14 language features, and memory-oriented C# (spans, ref types, pooling) for .NET 10 engineers.
-
What are generic classes in C#? Why do generics exist, how do you declare and close a generic type, and how do static fields behave for each constructed type such as Cache<int> and Cache<string>?
Generic classes: type parameters, open versus closed types, reification, per-type static state and when a class should be generic.
Junior
Theory
Generics
Β· π 3 follow-ups
-
How do generic methods work in C#? Explain how the compiler infers type arguments, when inference fails, and when you would make a method generic instead of the whole class.
Generic methods: declaration, type inference rules and limits, generic methods inside non-generic types, and design guidance.
Junior
Coding
Generics
Β· π 3 follow-ups Β· π 1 real-world
-
What are generic interfaces in C#? Explain why IEquatable<T>, IComparable<T> and IEnumerable<T> exist alongside their non-generic versions, how a type implements several closed versions of one interface, and how to design your own generic interface such as IRepository<T>.
Generic interfaces: type-safe contracts, avoiding boxing, implementing multiple closed interfaces, explicit implementation and designing generic abstractions.
Intermediate
Theory
Generics
Β· π 3 follow-ups Β· π 1 real-world
-
What generic constraints does C# support? Explain class, class?, struct, unmanaged, notnull, new(), base-class, interface, naked type, Enum and Delegate constraints, and the C# 13 allows ref struct anti-constraint, with an example of when you need each.
Every generic constraint in C# 14, what each enables, the order rules, and how constraints affect performance and API design.
Mid-Level
Theory
Generics
Β· π 3 follow-ups Β· π 1 real-world
-
What is covariance in C# generics? Explain the out modifier, why IEnumerable<string> converts to IEnumerable<object> but List<string> does not convert to List<object>, which BCL types are covariant, and the rules a covariant type parameter must follow.
Generic covariance: out T, output-only positions, reference conversions only, BCL examples and designing covariant interfaces and delegates.
Mid-Level
Theory
Generics
Β· π 3 follow-ups Β· π 1 real-world
-
What is contravariance in C# generics? Explain the in modifier, why an IComparer<object> or Action<object> can be used where IComparer<string> or Action<string> is expected, which BCL types are contravariant, and the gotcha with combining variant delegates.
Generic contravariance: in T, input-only positions, BCL comparers and delegates, and the run-time failure when combining variance-converted delegates.
Mid-Level
Theory
Generics
Β· π 2 follow-ups Β· π 1 real-world
-
A colleague cannot pass a List<Dog> to a method that takes List<Animal>, cannot assign Dictionary<string, List<string>> to IDictionary<string, IEnumerable<string>>, and cannot return Task<Dog> where Task<Animal> is expected. Explain invariance and how you would fix each case.
Generic invariance: why most generic types are invariant, how to diagnose CS1503/CS0266 conversion errors, and the fixes (covariant interfaces, generic methods with constraints, projection).
Mid-Level
Debugging
Generics
Β· π 3 follow-ups Β· π 1 real-world
-
How do generics perform in .NET? Explain how the JIT shares code for reference-type instantiations and specialises it for value types, what that means for typeof(T) checks, new T(), generic virtual methods and generic static caches, and how generics affect Native AOT size.
Generic performance internals: canonical shared code (__Canon), value-type specialisation, runtime generic dictionaries, constant folding of typeof(T), boxing avoidance and AOT code size.
Senior
Theory
Generics
Β· π 3 follow-ups Β· π 1 real-world
-
How do you register and resolve open generic types in .NET dependency injection, for example services.AddScoped(typeof(IRepository<>), typeof(Repository<>))? Explain how the container closes the type, how closed registrations override it, lifetimes, decorators and the limits of Microsoft.Extensions.DependencyInjection.
Open generic registration in Microsoft DI: how resolution closes types, precedence over closed registrations, IEnumerable resolution, decorators with Scrutor, validation and AOT limits.
Senior
Architecture
Generics
Β· π 3 follow-ups Β· π 1 real-world
-
What is a delegate in C#? Explain what a delegate object contains, how it is created and invoked, delegate equality, how instance and static method targets differ, what allocations happen, and how delegates compare with interfaces and function pointers.
Delegates as type-safe method references: anatomy (target plus method), creation and invocation, allocation and caching, equality, and choosing delegates versus interfaces or function pointers.
Junior
Theory
Delegates and Events
Β· π 3 follow-ups
-
What is a multicast delegate? Explain how += and -= build the invocation list, the order handlers run in, what happens to return values and exceptions, why delegates are thread-safe to read but events need care, and how GetInvocationList helps.
Multicast delegates: Delegate.Combine and Remove, immutable invocation lists, return values, exceptions stopping the chain, thread safety and invoking handlers individually.
Mid-Level
Theory
Delegates and Events
Β· π 2 follow-ups Β· π 1 real-world
-
What is an event in C#, and how is it different from a public delegate field? Explain what the event keyword generates, field-like events versus custom add/remove accessors, how to raise an event safely, and static events.
Events as an encapsulated publish/subscribe mechanism: compiler-generated add/remove, thread-safe subscription, raising safely, custom accessors and the risks of static events.
Mid-Level
Theory
Delegates and Events
Β· π 3 follow-ups Β· π 1 real-world
-
How should you design and handle events with EventHandler and EventHandler<TEventArgs>? Explain the sender and EventArgs conventions, async event handlers, and how event subscriptions cause memory leaks, including how you would find and fix one.
Event handler conventions (sender, EventArgs, EventArgs.Empty, OnXxx), async void handlers, and diagnosing and preventing event-subscription memory leaks with dotnet-dump and weak events.
Senior
Debugging
Delegates and Events
Β· π 3 follow-ups Β· π 1 real-world
-
What are Func, Action and Predicate in .NET? When do you use each, why can a Func<T, bool> not be passed where a Predicate<T> is expected, and when would you declare your own delegate type instead?
The built-in generic delegates Func, Action and Predicate: signatures, variance, where the BCL uses each, delegate type incompatibility and choosing custom delegates or expression trees.
Junior
Theory
Delegates and Events
Β· π 2 follow-ups
-
What are anonymous methods in C# (the delegate keyword syntax)? How do they differ from lambdas, what can they still do that lambdas cannot, can they be static, and would you use them in new code?
C# 2 anonymous methods: syntax, captured variables, omitting the parameter list, static anonymous methods, the lack of expression-tree conversion, and how they compare with lambdas.
Intermediate
Theory
Delegates and Events
Β· π 2 follow-ups
-
How do lambda expressions work in C#? Explain expression versus statement lambdas, natural types, static lambdas, attributes, explicit return types, default parameters (C# 12), parameter modifiers without types (C# 14), and how lambdas compile into closures.
Lambdas in C# 14: syntax forms, conversion to delegates or expression trees, natural type inference, modern features, closure compilation and allocation cost.
Mid-Level
Theory
Delegates and Events
Β· π 3 follow-ups Β· π 1 real-world
-
How does LINQ to Objects work under the hood? Explain how operators like Where and Select are implemented as extension methods and iterators, query syntax versus method syntax, streaming versus buffering operators, and the newer operators added in .NET 6 to .NET 10.
LINQ to Objects internals: extension methods over IEnumerable, iterator pipelines, operator fusion and fast paths, query syntax translation, streaming versus buffering, and modern operators such as Chunk, CountBy, Index and LeftJoin.
Mid-Level
Theory
LINQ
Β· π 3 follow-ups Β· π 1 real-world
-
What was LINQ to SQL, and which of its concepts still matter for a .NET 10 developer using EF Core? Explain the provider model, DataContext and change tracking, identity map, deferred loading, parameterised SQL generation and why LINQ to SQL is not available on modern .NET.
LINQ to SQL as the original IQueryable provider: its architecture and lasting concepts (translation, change tracking, identity map, lazy loading, parameterisation) and how they map to EF Core today.
Mid-Level
Theory
LINQ
Β· π 2 follow-ups Β· π 1 real-world
-
How does LINQ to Entities work in EF Core 10? Explain how a LINQ query is translated to SQL, what can and cannot be translated, client evaluation rules, tracking versus no-tracking, split queries, compiled queries, and how you inspect and tune the generated SQL.
LINQ to Entities with EF Core: the query pipeline, translation limits and client evaluation, tracking, projections, split queries, compiled queries and SQL inspection tools.
Senior
Theory
LINQ
Β· π 3 follow-ups Β· π 1 real-world
-
A colleague's LINQ code behaves strangely: a filtered list seems to change after it was built, a database query throws ObjectDisposedException, logging shows the same query running three times, and an exception appears far from the line that caused it. Explain deferred execution and how you would debug and fix each symptom.
Deferred execution in practice: when queries run, captured variables, multiple enumeration, disposed contexts, late exceptions, and the tools and rules that prevent these bugs.
Mid-Level
Debugging
LINQ
Β· π 3 follow-ups Β· π 1 real-world