<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Libin Tom Baby</title>
    <description>The latest articles on Forem by Libin Tom Baby (@libintombaby).</description>
    <link>https://forem.com/libintombaby</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2726247%2F4e8f6927-053a-4f4d-ab93-aee2a8150e26.png</url>
      <title>Forem: Libin Tom Baby</title>
      <link>https://forem.com/libintombaby</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/libintombaby"/>
    <language>en</language>
    <item>
      <title>How Dependency Injection Works Internally in .NET</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Wed, 15 Apr 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/how-dependency-injection-works-internally-in-net-30pe</link>
      <guid>https://forem.com/libintombaby/how-dependency-injection-works-internally-in-net-30pe</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;ServiceCollection, IServiceProvider, resolution chain, scope factory, how the container builds the object graph&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every ASP.NET Core application uses dependency injection.&lt;/p&gt;

&lt;p&gt;But most developers only know how to &lt;em&gt;use&lt;/em&gt; it — not how the container actually works under the hood.&lt;/p&gt;

&lt;p&gt;This guide explains the mechanics: how services are registered, how the container resolves them, how lifetimes are enforced, and the mistakes that silently break things.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Three Building Blocks&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;IServiceCollection&lt;/code&gt; — the registration
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;IServiceCollection&lt;/code&gt; is just a list. When you call &lt;code&gt;AddScoped&amp;lt;T&amp;gt;()&lt;/code&gt;, you're adding a &lt;code&gt;ServiceDescriptor&lt;/code&gt; to that list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IUserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEmailService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EmailService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing is created yet. You're just declaring what to build.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;IServiceProvider&lt;/code&gt; — the container
&lt;/h3&gt;

&lt;p&gt;When &lt;code&gt;.Build()&lt;/code&gt; is called, the &lt;code&gt;IServiceCollection&lt;/code&gt; is compiled into an &lt;code&gt;IServiceProvider&lt;/code&gt; — the actual DI container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// IServiceProvider is created here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Resolution — how objects are constructed
&lt;/h3&gt;

&lt;p&gt;When a service is requested, the container:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Looks up the registered &lt;code&gt;ServiceDescriptor&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Checks if an existing instance should be returned (singleton/scoped)&lt;/li&gt;
&lt;li&gt;If not, creates a new instance using the registered constructor&lt;/li&gt;
&lt;li&gt;Resolves all constructor dependencies recursively&lt;/li&gt;
&lt;li&gt;Returns the fully-constructed object&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Three Lifetimes — Explained Internally&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Singleton
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IConfigService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ConfigService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One instance created on first request. Stored in the root container. Returned for every subsequent request — forever.&lt;/p&gt;

&lt;p&gt;Use for: stateless services, configuration, caches, HTTP clients.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scoped
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IDbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AppDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One instance per HTTP request. Created when the scope starts, disposed when it ends.&lt;/p&gt;

&lt;p&gt;In ASP.NET Core, a new &lt;code&gt;IServiceScope&lt;/code&gt; is created for each HTTP request. All scoped services within that request share the same instance.&lt;/p&gt;

&lt;p&gt;Use for: database contexts, unit-of-work, per-request state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transient
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEmailService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EmailService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A new instance every single time the service is requested. No sharing.&lt;/p&gt;

&lt;p&gt;Use for: lightweight, stateless services where a fresh instance is always needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How Constructor Injection Works&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The container uses reflection to inspect the constructor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IDbContext&lt;/span&gt; &lt;span class="n"&gt;_db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IEmailService&lt;/span&gt; &lt;span class="n"&gt;_email&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;OrderService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;IDbContext&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;IEmailService&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_db&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;IOrderService&lt;/code&gt; is requested, the container:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Finds &lt;code&gt;OrderService&lt;/code&gt; as the implementation&lt;/li&gt;
&lt;li&gt;Inspects its constructor via reflection&lt;/li&gt;
&lt;li&gt;Resolves &lt;code&gt;IDbContext&lt;/code&gt;, &lt;code&gt;IEmailService&lt;/code&gt;, and &lt;code&gt;ILogger&amp;lt;OrderService&amp;gt;&lt;/code&gt; recursively&lt;/li&gt;
&lt;li&gt;Creates the &lt;code&gt;OrderService&lt;/code&gt; instance with all dependencies injected&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If any dependency is not registered, an &lt;code&gt;InvalidOperationException&lt;/code&gt; is thrown at resolution time.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Captive Dependency Problem&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The most dangerous lifetime mistake.&lt;/p&gt;

&lt;p&gt;A singleton depending on a scoped service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Captive dependency — runtime exception or silent bug&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReportService&lt;/span&gt; &lt;span class="c1"&gt;// Singleton&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ReportService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IDbContext&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// IDbContext is Scoped&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A singleton lives forever. A scoped service is tied to a request. The scoped service is never released — it becomes effectively a singleton with incorrect state.&lt;/p&gt;

&lt;p&gt;ASP.NET Core detects this in Development mode. Enable it explicitly in Production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDefaultServiceProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValidateScopes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValidateOnBuild&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Resolving Services Manually&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// From IServiceProvider directly&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Creating a scope manually (e.g. in a background service)&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServiceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never resolve scoped services from the root &lt;code&gt;IServiceProvider&lt;/code&gt; — they won't be disposed correctly. Always create a scope first.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Interview-Ready Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IServiceCollection&lt;/code&gt; is just a list of descriptors — nothing is created at registration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IServiceProvider&lt;/code&gt; is the compiled container that resolves and creates objects&lt;/li&gt;
&lt;li&gt;Resolution works by inspecting constructors via reflection and recursively resolving dependencies&lt;/li&gt;
&lt;li&gt;Singleton = one instance forever; Scoped = one per request; Transient = always new&lt;/li&gt;
&lt;li&gt;Captive dependency = singleton holding a scoped service — causes bugs or exceptions&lt;/li&gt;
&lt;li&gt;Always use &lt;code&gt;CreateScope()&lt;/code&gt; when resolving scoped services in background contexts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ValidateOnBuild = true&lt;/code&gt; catches registration errors at startup, not at runtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"The .NET DI container is built from IServiceCollection — a list of service registrations. At build time, it compiles into an IServiceProvider. When a service is requested, the container uses reflection to inspect the constructor, recursively resolves each dependency, respects lifetimes, and returns the fully constructed object. The main lifetime trap is the captive dependency — a singleton holding a scoped service, which prevents proper disposal."&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>dependencyinjection</category>
      <category>csharp</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The Middleware Pipeline in ASP.NET Core — How It Really Works</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Mon, 13 Apr 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/the-middleware-pipeline-in-aspnet-core-how-it-really-works-48bf</link>
      <guid>https://forem.com/libintombaby/the-middleware-pipeline-in-aspnet-core-how-it-really-works-48bf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Use, Run, Map, short-circuit, ordering, custom middleware&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every HTTP request in ASP.NET Core passes through a pipeline of middleware components before reaching your controller.&lt;/p&gt;

&lt;p&gt;Understanding this pipeline is essential — it's where logging, authentication, exception handling, CORS, routing, and response caching all live.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Is Middleware?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Middleware is software assembled into a pipeline to handle requests and responses.&lt;/p&gt;

&lt;p&gt;Each middleware component:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receives the incoming &lt;code&gt;HttpContext&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Optionally does something with the request&lt;/li&gt;
&lt;li&gt;Calls the next middleware in the chain&lt;/li&gt;
&lt;li&gt;Optionally does something with the response on the way back
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request  → [Logging] → [Auth] → [CORS] → [Routing] → [Handler]
Response ← [Logging] ← [Auth] ← [CORS] ← [Routing] ← [Handler]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;The Three Methods: Use, Run, Map&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Use&lt;/code&gt; — calls the next component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Before next middleware"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After next middleware"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;Run&lt;/code&gt; — terminal, does NOT call next
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello — pipeline stops here"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;Map&lt;/code&gt; — branches based on path
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/health"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Healthy"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Ordering Matters — A Lot&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The order you register middleware is the order it runs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseExceptionHandler&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;    &lt;span class="c1"&gt;// 1 — catch all unhandled exceptions first&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;    &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseCors&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;                &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthentication&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;      &lt;span class="c1"&gt;// 4 — who are you?&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       &lt;span class="c1"&gt;// 5 — what can you do?&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRateLimiter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;         &lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapControllers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;         &lt;span class="c1"&gt;// 7 — route to controller&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Getting the order wrong causes real bugs. Authentication before exception handling means auth errors won't be caught cleanly.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Short-Circuiting the Pipeline&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Middleware can stop the request from proceeding further.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-API-Key"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Missing API key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ← Does NOT call next — pipeline stops here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how authentication middleware works — validate the token, let through or short-circuit with 401.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Building Custom Middleware&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Inline (simple cases)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Custom-Header"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyApp"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Class-based (preferred for complex middleware)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RequestTimingMiddleware&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;RequestDelegate&lt;/span&gt; &lt;span class="n"&gt;_next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RequestTimingMiddleware&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;RequestTimingMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestDelegate&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RequestTimingMiddleware&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_next&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;InvokeAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stopwatch&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;_next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Request {Method} {Path} completed in {ElapsedMs}ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElapsedMilliseconds&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Extension method&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RequestTimingMiddlewareExtensions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="nf"&gt;UseRequestTiming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseMiddleware&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RequestTimingMiddleware&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRequestTiming&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Real-World Scenarios&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Logging every request and response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Incoming: {Method} {Path}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Outgoing: {StatusCode}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding a correlation ID to every response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Correlation-Id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGuid&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Interview-Ready Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Middleware forms a bidirectional pipeline — request goes in, response comes back&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Use&lt;/code&gt; = calls next, &lt;code&gt;Run&lt;/code&gt; = terminal, &lt;code&gt;Map&lt;/code&gt; = branch by path&lt;/li&gt;
&lt;li&gt;Order of registration = order of execution&lt;/li&gt;
&lt;li&gt;Short-circuiting stops the pipeline — used by auth, rate limiting, validation&lt;/li&gt;
&lt;li&gt;Custom middleware goes in a class implementing &lt;code&gt;InvokeAsync(HttpContext)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Exception handling middleware should be first (outermost) so it catches everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"ASP.NET Core middleware forms a pipeline where each component can process the request before passing it to the next, and then process the response on the way back. The order matters — exception handling goes first, then CORS, then authentication, then routing. You can short-circuit the pipeline at any point, which is how auth middleware rejects unauthorised requests."&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>aspnetcore</category>
      <category>csharp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Threading vs Tasks vs Parallelism — The Complete .NET Concurrency Guide</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Sat, 11 Apr 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/threading-vs-tasks-vs-parallelism-the-complete-net-concurrency-guide-7dj</link>
      <guid>https://forem.com/libintombaby/threading-vs-tasks-vs-parallelism-the-complete-net-concurrency-guide-7dj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Thread, ThreadPool, Task, Parallel.For, PLINQ, when to use each&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Concurrency is one of the most misunderstood areas of .NET development.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Thread&lt;/code&gt;, &lt;code&gt;Task&lt;/code&gt;, &lt;code&gt;Parallel&lt;/code&gt;, &lt;code&gt;async/await&lt;/code&gt; — developers often use these interchangeably without understanding what they actually do. The wrong choice costs you performance, correctness, and scalability.&lt;/p&gt;

&lt;p&gt;This guide breaks down each concept clearly, with real-world guidance on when to use which.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; Another post &lt;em&gt;&lt;a href="https://dev.to/libintombaby/asyncawait-in-c-a-deep-dive-into-how-asynchronous-programming-really-works-3f01"&gt;Async/Await in C# — A Deep Dive Into How Asynchronous Programming Really Works&lt;/a&gt;&lt;/em&gt; covers the difference between asynchrony and parallelism briefly. This post goes much deeper into the underlying primitives — &lt;code&gt;Thread&lt;/code&gt;, &lt;code&gt;ThreadPool&lt;/code&gt;, &lt;code&gt;Task&lt;/code&gt;, and &lt;code&gt;Parallel&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Mental Model&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before the code, get the mental model right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concurrency&lt;/strong&gt; — dealing with multiple things at once (managing)&lt;br&gt;
&lt;strong&gt;Parallelism&lt;/strong&gt; — doing multiple things at once (executing)&lt;br&gt;
&lt;strong&gt;Asynchrony&lt;/strong&gt; — starting something and doing other work while waiting&lt;/p&gt;

&lt;p&gt;These are not the same thing.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Thread — The Low-Level Primitive&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;Thread&lt;/code&gt; is an OS-level execution unit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Running on thread &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Wait for it to finish&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What you get
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Full control over the thread lifecycle&lt;/li&gt;
&lt;li&gt;Can set priority, name, apartment state&lt;/li&gt;
&lt;li&gt;Can be a foreground or background thread&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What it costs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Creating a thread allocates ~1MB of stack memory&lt;/li&gt;
&lt;li&gt;OS scheduling overhead on every context switch&lt;/li&gt;
&lt;li&gt;You are responsible for lifecycle management&lt;/li&gt;
&lt;li&gt;Does not integrate with async/await&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to use Thread directly
&lt;/h3&gt;

&lt;p&gt;Almost never in modern .NET. Use &lt;code&gt;Task&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;The only remaining valid use case is COM interop requiring a specific apartment state (STA thread for WinForms/WPF dialogs).&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;ThreadPool — Reusing Threads&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;ThreadPool&lt;/code&gt; manages a pool of pre-created threads that can be reused.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;ThreadPool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;QueueUserWorkItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running on a pool thread"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't create threads — you submit work items and the pool decides which thread handles it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No thread creation overhead&lt;/li&gt;
&lt;li&gt;Threads are reused across work items&lt;/li&gt;
&lt;li&gt;The runtime tunes the pool size automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to use ThreadPool directly
&lt;/h3&gt;

&lt;p&gt;You don't. &lt;code&gt;Task.Run()&lt;/code&gt; wraps &lt;code&gt;ThreadPool&lt;/code&gt; and gives you a much better API.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Task — The Modern Standard&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Task&lt;/code&gt; is the recommended abstraction for concurrent and asynchronous work in .NET.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// CPU-bound work on the ThreadPool&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;ExpensiveCalculation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Task represents a promise
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;Task&lt;/code&gt; is a promise that work will complete at some point.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Task&lt;/code&gt; — work with no return value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Task&amp;lt;T&amp;gt;&lt;/code&gt; — work that returns a value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ValueTask&amp;lt;T&amp;gt;&lt;/code&gt; — lightweight Task for high-frequency paths&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Combining Tasks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Run two tasks in parallel and wait for both&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;DoWork1&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;DoWork2&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Wait for the first one to finish&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;winner&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAny&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;async/await — Asynchrony Without Blocking&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; is not about parallelism.&lt;/p&gt;

&lt;p&gt;It is about &lt;strong&gt;freeing threads while waiting for I/O&lt;/strong&gt; — network calls, database queries, file reads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The thread is released while waiting for the HTTP response&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The critical distinction
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Waiting for a database query&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Waiting for an HTTP call&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Running a heavy calculation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Task.Run()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Running multiple calculations at once&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Parallel.For&lt;/code&gt; / &lt;code&gt;Task.WhenAll&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Parallel — True CPU Parallelism&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Parallel&lt;/code&gt; splits work across multiple CPU cores simultaneously.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallel.For
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;For&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;ProcessItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parallel.ForEach
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetLargeCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PLINQ
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsParallel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When to use Parallel
&lt;/h3&gt;

&lt;p&gt;Only for &lt;strong&gt;CPU-bound&lt;/strong&gt; work that can be split into independent chunks.&lt;/p&gt;

&lt;p&gt;Never use &lt;code&gt;Parallel&lt;/code&gt; for I/O-bound work — it wastes threads and can cause thread starvation.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Decision Framework&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is the work CPU-bound or I/O-bound?
│
├── I/O-bound (network, DB, file)
│   └── Use async/await
│       └── Task.Run is NOT needed here
│
└── CPU-bound (calculations, image processing)
    │
    ├── Single heavy operation
    │   └── Task.Run(() =&amp;gt; HeavyWork())
    │
    └── Many independent items
        └── Parallel.For / Parallel.ForEach / PLINQ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Common Mistakes&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mistake 1: Using Task.Run for I/O-bound work
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Wrong — wastes a thread waiting for I/O&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Correct — no thread needed while waiting&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mistake 2: Using async/await for CPU-bound work
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Looks async but blocks the thread&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ComputeAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;HeavyCpuWork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// No await — just pretending to be async&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Correct — offload to ThreadPool&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ComputeAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;HeavyCpuWork&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mistake 3: Parallel for I/O
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ This spawns threads and blocks them all waiting for HTTP&lt;/span&gt;
&lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Blocking!&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Use Task.WhenAll for parallel async I/O&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Interview-Ready Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Thread&lt;/code&gt; is the OS-level primitive — powerful but expensive and rarely needed directly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ThreadPool&lt;/code&gt; recycles threads — &lt;code&gt;Task.Run&lt;/code&gt; wraps it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Task&lt;/code&gt; is the standard abstraction for concurrent work&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; frees threads during I/O — it is not parallelism&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Parallel.For&lt;/code&gt; / &lt;code&gt;Parallel.ForEach&lt;/code&gt; distributes CPU work across cores&lt;/li&gt;
&lt;li&gt;I/O-bound → &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt;; CPU-bound single op → &lt;code&gt;Task.Run&lt;/code&gt;; CPU-bound many items → &lt;code&gt;Parallel&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Never use &lt;code&gt;Parallel&lt;/code&gt; for I/O — it wastes threads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;"Threads are the OS-level unit of execution — expensive to create. Tasks abstract over the ThreadPool and support async/await. Async/await is about freeing threads during I/O, not parallelism. Parallelism means actually executing work on multiple cores simultaneously — that's what Parallel.For and Task.WhenAll are for. The golden rule: async/await for I/O-bound, Parallel or Task.Run for CPU-bound."&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




</description>
      <category>dotnet</category>
      <category>async</category>
      <category>performance</category>
      <category>csharp</category>
    </item>
    <item>
      <title>IAsyncEnumerable Explained — Async Streams in .NET</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Thu, 09 Apr 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/iasyncenumerable-explained-async-streams-in-net-2854</link>
      <guid>https://forem.com/libintombaby/iasyncenumerable-explained-async-streams-in-net-2854</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;IAsyncEnumerable, yield return, cancellation tokens, vs IEnumerable, real-world streaming&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most developers know &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;async/await&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; — lets you iterate a sequence.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; — lets you do I/O without blocking threads.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; — introduced in C# 8 — combines both, and it solves a problem that neither alone handles well.&lt;/p&gt;

&lt;p&gt;It lets you iterate a sequence &lt;strong&gt;asynchronously&lt;/strong&gt; — yielding items one at a time as they become available, without loading everything into memory first.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Problem They Solve&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine reading 100,000 records from a database and returning them to the caller.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: Return everything at once
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAllOrdersAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Loads everything into memory&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Memory spikes. The caller waits for the entire load.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: Synchronous yield
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAllOrders&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Blocks the thread&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Streams items one at a time, but blocks the thread on every read.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 3: IAsyncEnumerable — the right way
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAllOrdersAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ✅ Non-blocking, streamed one at a time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Items are produced and consumed one at a time, without blocking the thread, without loading everything into memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How It Works&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is the async version of &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Produce an Async Stream
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;async&lt;/code&gt;, return &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;, and &lt;code&gt;yield return&lt;/code&gt; each item.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Producer&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GenerateNumbersAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Simulates async work&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The producer can &lt;code&gt;await&lt;/code&gt; before yielding each item. Each call to &lt;code&gt;yield return&lt;/code&gt; sends one item to the consumer, then pauses until the consumer requests the next one.&lt;/p&gt;




&lt;h3&gt;
  
  
  How to Consume an Async Stream
&lt;/h3&gt;

&lt;p&gt;The consumer uses &lt;code&gt;await foreach&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Consumer&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;GenerateNumbersAsync&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the async equivalent of &lt;code&gt;foreach&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Each iteration &lt;code&gt;await&lt;/code&gt;s the next item without blocking the thread.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Cancellation Support&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Always support cancellation in long-running async streams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Producer with cancellation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetOrdersAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EnumeratorCancellation&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;WithCancellation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Consumer with cancellation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CancellationTokenSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;GetOrdersAsync&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;WithCancellation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without cancellation, a long-running stream can run indefinitely.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;IAsyncEnumerable vs IEnumerable&lt;/strong&gt;
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Execution&lt;/td&gt;
&lt;td&gt;Synchronous&lt;/td&gt;
&lt;td&gt;Asynchronous&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thread blocking&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use case&lt;/td&gt;
&lt;td&gt;In-memory data&lt;/td&gt;
&lt;td&gt;I/O-bound data sources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iteration&lt;/td&gt;
&lt;td&gt;&lt;code&gt;foreach&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;await foreach&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cancellation&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (CancellationToken)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Can load all at once&lt;/td&gt;
&lt;td&gt;Streams item by item&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;IAsyncEnumerable vs Task&amp;lt;List&amp;lt;T&amp;gt;&amp;gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;Task&amp;lt;List&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Returns&lt;/td&gt;
&lt;td&gt;All items at once&lt;/td&gt;
&lt;td&gt;One at a time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory usage&lt;/td&gt;
&lt;td&gt;High (all in memory)&lt;/td&gt;
&lt;td&gt;Low (streaming)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to first item&lt;/td&gt;
&lt;td&gt;After all items loaded&lt;/td&gt;
&lt;td&gt;Immediately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Small datasets&lt;/td&gt;
&lt;td&gt;Large or infinite streams&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Real-World Scenarios&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Scenario 1: Streaming database records
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetLowStockProductsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EnumeratorCancellation&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Products&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StockLevel&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithCancellation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Scenario 2: Streaming an external API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WeatherReading&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;StreamWeatherAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EnumeratorCancellation&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsCancellationRequested&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reading&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_weatherApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetLatestAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;reading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Scenario 3: Reading a large file line by line
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ReadLinesAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EnumeratorCancellation&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadLinesAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Scenario 4: Exposing async streams from an API endpoint (ASP.NET Core)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"stream"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;StreamOrders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EnumeratorCancellation&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetOrdersAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ASP.NET Core supports returning &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; directly from action methods.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Interview-Ready Summary&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; lets you stream data asynchronously — one item at a time&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;yield return&lt;/code&gt; in an &lt;code&gt;async&lt;/code&gt; method returning &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; to produce a stream&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;await foreach&lt;/code&gt; to consume it&lt;/li&gt;
&lt;li&gt;Always use &lt;code&gt;[EnumeratorCancellation] CancellationToken&lt;/code&gt; in producers&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;.WithCancellation(ct)&lt;/code&gt; in consumers&lt;/li&gt;
&lt;li&gt;Prefer &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; over &lt;code&gt;Task&amp;lt;List&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; when datasets are large, unbounded, or I/O-bound&lt;/li&gt;
&lt;li&gt;ASP.NET Core can return &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; directly from controller actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"IAsyncEnumerable allows asynchronous iteration — yielding items one at a time as they're available, instead of loading everything into memory first. It's ideal for large database queries, external API streams, and file processing. You produce it with &lt;code&gt;yield return&lt;/code&gt; in an async method, and consume it with &lt;code&gt;await foreach&lt;/code&gt;."&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;⭐ &lt;strong&gt;Add-On — LINQ and IAsyncEnumerable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As of .NET 9, LINQ supports &lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; natively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .NET 9+&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;GetOrdersAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before .NET 9, you needed the &lt;code&gt;System.Linq.Async&lt;/code&gt; NuGet package for this.&lt;br&gt;
Now it's built in — making async streams a first-class citizen alongside standard LINQ.&lt;/p&gt;




</description>
      <category>dotnet</category>
      <category>async</category>
      <category>csharp</category>
      <category>performance</category>
    </item>
    <item>
      <title>Record Types in C# — Immutability, Equality, and When to Use Them</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Wed, 08 Apr 2026 07:15:43 +0000</pubDate>
      <link>https://forem.com/libintombaby/record-types-in-c-immutability-equality-and-when-to-use-them-4imp</link>
      <guid>https://forem.com/libintombaby/record-types-in-c-immutability-equality-and-when-to-use-them-4imp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;record, record struct, init, with expressions, value equality&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Record Types in C#&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Records were introduced in C# 9 and enhanced in C# 10.&lt;/p&gt;

&lt;p&gt;They look like classes. They behave differently.&lt;/p&gt;

&lt;p&gt;Most developers use records without fully understanding what makes them special — and more importantly, when they're the right tool and when they're not.&lt;/p&gt;

&lt;p&gt;This guide breaks down everything you need to know.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;What is a Record?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A record is a reference type (like a class) that is designed for &lt;strong&gt;immutable data&lt;/strong&gt; with &lt;strong&gt;value-based equality&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one line gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A constructor&lt;/li&gt;
&lt;li&gt;Public &lt;code&gt;init&lt;/code&gt;-only properties&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ToString()&lt;/code&gt; override&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Equals()&lt;/code&gt; and &lt;code&gt;GetHashCode()&lt;/code&gt; based on values — not references&lt;/li&gt;
&lt;li&gt;Deconstruction support&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;with&lt;/code&gt; expression support&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Value Equality — The Core Difference&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;With a class, two objects are equal only if they are the &lt;strong&gt;same object in memory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With a record, two objects are equal if their &lt;strong&gt;values are the same&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Class (reference equality)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PersonClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PersonClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// False — different objects in memory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Record (value equality)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// True — same values&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the single most important thing to understand about records.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Immutability With &lt;code&gt;init&lt;/code&gt;&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Record properties use &lt;code&gt;init&lt;/code&gt; accessors by default — they can only be set during construction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Compile error — init-only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes records safe to pass around without defensive copying.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;The &lt;code&gt;with&lt;/code&gt; Expression&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;You cannot mutate a record. But you can create a &lt;strong&gt;modified copy&lt;/strong&gt; using &lt;code&gt;with&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;updated&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;31&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Person { Name = Alice, Age = 30 }&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Person { Name = Alice, Age = 31 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The original is untouched.&lt;br&gt;
&lt;code&gt;with&lt;/code&gt; creates a shallow copy with the specified properties replaced.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Deconstruction&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Records support positional deconstruction automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Alice&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  &lt;strong&gt;Record vs Class — Feature Comparison&lt;/strong&gt;
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Record&lt;/th&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Type&lt;/td&gt;
&lt;td&gt;Reference type&lt;/td&gt;
&lt;td&gt;Reference type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Equality&lt;/td&gt;
&lt;td&gt;Value-based&lt;/td&gt;
&lt;td&gt;Reference-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Immutability&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;init&lt;/code&gt; by default&lt;/td&gt;
&lt;td&gt;Mutable by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;with&lt;/code&gt; expression&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inheritance&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToString()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto-generated&lt;/td&gt;
&lt;td&gt;Default object.ToString()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;DTOs, value objects, API responses&lt;/td&gt;
&lt;td&gt;Entities, services, stateful objects&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Record Struct (C# 10)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;C# 10 introduced &lt;code&gt;record struct&lt;/code&gt; — a &lt;strong&gt;value type&lt;/strong&gt; record.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// True — value equality&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;record struct&lt;/code&gt; gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Value type semantics (stack allocation, no GC pressure)&lt;/li&gt;
&lt;li&gt;Value equality&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;with&lt;/code&gt; expression&lt;/li&gt;
&lt;li&gt;No heap allocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;code&gt;record struct&lt;/code&gt; for small, frequently used, immutable value objects.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;When to Use Records&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Use records for
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DTOs (Data Transfer Objects)&lt;/strong&gt; — data flowing between layers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API request/response models&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value objects&lt;/strong&gt; in Domain-Driven Design&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Query results&lt;/strong&gt; that should not be mutated&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configuration objects&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Any data where equality means "same values"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Do NOT use records for
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain entities&lt;/strong&gt; that have identity (an &lt;code&gt;Order&lt;/code&gt; with an ID is not equal to another &lt;code&gt;Order&lt;/code&gt; with the same values — they are separate things)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Services and repositories&lt;/strong&gt; — these have behaviour, not just data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Objects with complex mutable state&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Real-World Example&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Perfect use of record — API response DTO&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;OrderResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;CustomerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;TotalAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;CreatedAt&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ With expression for building variations in tests&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;baseOrder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;OrderResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;150.00m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;updatedOrder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;baseOrder&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;TotalAmount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;200.00m&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Value equality in assertions&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;OrderResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;150.00m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Works because of value equality&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  &lt;strong&gt;Record Inheritance&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Records support inheritance — but with one rule:&lt;/p&gt;

&lt;p&gt;A record can only inherit from another record (not a class).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Breed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Rex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Labrador"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Dog { Name = Rex, Breed = Labrador }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Equality checks include all derived type properties.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Interview-Ready Summary&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Records are reference types with value-based equality&lt;/li&gt;
&lt;li&gt;Two records with the same values are considered equal&lt;/li&gt;
&lt;li&gt;Properties are &lt;code&gt;init&lt;/code&gt;-only by default — immutable after construction&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;with&lt;/code&gt; to create modified copies without mutating the original&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;record struct&lt;/code&gt; is a value type record — no heap allocation&lt;/li&gt;
&lt;li&gt;Use records for DTOs, API models, value objects&lt;/li&gt;
&lt;li&gt;Do not use records for domain entities that have identity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Records are designed for immutable data with value-based equality. Unlike classes where equality means same reference, two records with the same values are equal. The &lt;code&gt;with&lt;/code&gt; expression lets you produce modified copies non-destructively. They're ideal for DTOs and value objects, but not for domain entities where identity matters more than content."&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;⭐ &lt;strong&gt;Add-On — Records in Pattern Matching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Records work exceptionally well with C# pattern matching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Radius&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;GetArea&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PI&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;                      &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unknown shape"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Positional patterns work directly with record deconstruction — no extra code needed.&lt;/p&gt;




</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>recordtype</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Value Types vs Reference Types, Struct vs Class, and Boxing &amp; Unboxing — The Complete C# Guide</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Mon, 30 Mar 2026 05:07:40 +0000</pubDate>
      <link>https://forem.com/libintombaby/value-types-vs-reference-types-struct-vs-class-and-boxing-unboxing-the-complete-c-guide-2cif</link>
      <guid>https://forem.com/libintombaby/value-types-vs-reference-types-struct-vs-class-and-boxing-unboxing-the-complete-c-guide-2cif</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Value/reference types, stack vs heap, struct vs class, boxing/unboxing performance traps&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Value Types vs Reference Types, Struct vs Class, and Boxing &amp;amp; Unboxing&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;These three topics are deeply connected.&lt;/p&gt;

&lt;p&gt;You cannot fully understand &lt;code&gt;struct vs class&lt;/code&gt; without understanding the stack and heap.&lt;br&gt;&lt;br&gt;
You cannot fully understand boxing and unboxing without understanding value and reference types.&lt;/p&gt;

&lt;p&gt;This guide covers all three together — the way they should be taught.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;How .NET Manages Memory&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Before anything else, you need to understand two memory regions.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Stack&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fast allocation and deallocation&lt;/li&gt;
&lt;li&gt;LIFO (Last In, First Out) structure&lt;/li&gt;
&lt;li&gt;Stores value types and method call frames&lt;/li&gt;
&lt;li&gt;Memory is automatically reclaimed when the method exits&lt;/li&gt;
&lt;li&gt;Limited in size&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Heap&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Slower allocation&lt;/li&gt;
&lt;li&gt;Stores reference types (objects)&lt;/li&gt;
&lt;li&gt;Managed by the Garbage Collector (GC)&lt;/li&gt;
&lt;li&gt;Much larger than the stack&lt;/li&gt;
&lt;li&gt;Memory is reclaimed by the GC, not deterministically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This distinction is the foundation of everything that follows.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Value Types&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A value type holds its data &lt;strong&gt;directly&lt;/strong&gt; in memory.&lt;/p&gt;

&lt;p&gt;When you assign a value type to another variable, a &lt;strong&gt;copy&lt;/strong&gt; is made.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 10 — not affected&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common value types
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, &lt;code&gt;double&lt;/code&gt;, &lt;code&gt;decimal&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;char&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DateTime&lt;/code&gt;, &lt;code&gt;TimeSpan&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;struct&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;enum&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Nullable value types (&lt;code&gt;int?&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where they live
&lt;/h3&gt;

&lt;p&gt;Value types declared as &lt;strong&gt;local variables&lt;/strong&gt; live on the &lt;strong&gt;stack&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Value types declared as &lt;strong&gt;fields inside a class&lt;/strong&gt; live on the &lt;strong&gt;heap&lt;/strong&gt; alongside the object.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Reference Types&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A reference type stores a &lt;strong&gt;reference (pointer)&lt;/strong&gt; to the actual data on the heap.&lt;/p&gt;

&lt;p&gt;When you assign a reference type to another variable, both variables point to the &lt;strong&gt;same object&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Bob — both point to the same object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common reference types
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;class&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;interface&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delegate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Arrays&lt;/li&gt;
&lt;li&gt;&lt;code&gt;object&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where they live
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;reference&lt;/strong&gt; (the pointer) can live on the stack.&lt;br&gt;&lt;br&gt;
The &lt;strong&gt;actual object data&lt;/strong&gt; always lives on the &lt;strong&gt;heap&lt;/strong&gt;.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;The Key Difference — Side by Side&lt;/strong&gt;
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Value Type&lt;/th&gt;
&lt;th&gt;Reference Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stores&lt;/td&gt;
&lt;td&gt;Actual data&lt;/td&gt;
&lt;td&gt;Reference to data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assignment&lt;/td&gt;
&lt;td&gt;Creates a copy&lt;/td&gt;
&lt;td&gt;Shares the reference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Stack (usually)&lt;/td&gt;
&lt;td&gt;Heap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Null&lt;/td&gt;
&lt;td&gt;Not nullable by default&lt;/td&gt;
&lt;td&gt;Nullable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GC involvement&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Examples&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;int&lt;/code&gt;, &lt;code&gt;struct&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;class&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Struct vs Class&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;struct&lt;/code&gt; is a value type.&lt;br&gt;&lt;br&gt;
&lt;code&gt;class&lt;/code&gt; is a reference type.&lt;/p&gt;

&lt;p&gt;This single difference drives all the behaviour below.&lt;/p&gt;
&lt;h3&gt;
  
  
  Struct example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// copy&lt;/span&gt;

&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1 — unaffected&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 99&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Class example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// same reference&lt;/span&gt;

&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 99 — both affected&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 99&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;strong&gt;Struct vs Class — Feature Comparison&lt;/strong&gt;
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Struct&lt;/th&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Type&lt;/td&gt;
&lt;td&gt;Value type&lt;/td&gt;
&lt;td&gt;Reference type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Stack (typically)&lt;/td&gt;
&lt;td&gt;Heap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inheritance&lt;/td&gt;
&lt;td&gt;Cannot inherit&lt;/td&gt;
&lt;td&gt;Supports inheritance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default constructor&lt;/td&gt;
&lt;td&gt;Implicit (zeroes fields)&lt;/td&gt;
&lt;td&gt;Can define&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nullable&lt;/td&gt;
&lt;td&gt;No (unless &lt;code&gt;Nullable&amp;lt;T&amp;gt;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passed by&lt;/td&gt;
&lt;td&gt;Value (copy)&lt;/td&gt;
&lt;td&gt;Reference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GC pressure&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Small, immutable data&lt;/td&gt;
&lt;td&gt;Complex objects, behaviour&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;When to Use Struct&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Use a &lt;code&gt;struct&lt;/code&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The data is small (typically under 16 bytes)&lt;/li&gt;
&lt;li&gt;The type is logically a single value (a point, a colour, a coordinate)&lt;/li&gt;
&lt;li&gt;Immutability is desired&lt;/li&gt;
&lt;li&gt;You want to avoid heap allocation and GC pressure&lt;/li&gt;
&lt;li&gt;The type will be used heavily in tight loops or collections
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Good struct candidates&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Coordinate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Lat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Lon&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Rgb&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;G&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Money&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  When NOT to use struct
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The data is large (copying becomes expensive)&lt;/li&gt;
&lt;li&gt;The type needs inheritance&lt;/li&gt;
&lt;li&gt;The type has mutable state that gets passed around&lt;/li&gt;
&lt;li&gt;The type will be used as an interface (triggers boxing — explained below)&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Boxing and Unboxing&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Boxing and unboxing happen when a value type is treated as a reference type.&lt;/p&gt;
&lt;h3&gt;
  
  
  Boxing
&lt;/h3&gt;

&lt;p&gt;Converting a value type to &lt;code&gt;object&lt;/code&gt; (or an interface type).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;boxed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Boxing — a copy is placed on the heap&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens under the hood:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Memory is allocated on the heap&lt;/li&gt;
&lt;li&gt;The value is copied from the stack into the heap object&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;object&lt;/code&gt; variable holds a reference to that heap memory&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Unboxing
&lt;/h3&gt;

&lt;p&gt;Converting a boxed &lt;code&gt;object&lt;/code&gt; back to a value type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;boxed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;unboxed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;boxed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Unboxing — copies value back from heap to stack&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens under the hood:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The runtime checks the type matches&lt;/li&gt;
&lt;li&gt;The value is copied from the heap back to the stack&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Why Boxing is Expensive&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Boxing seems harmless. It isn't.&lt;/p&gt;

&lt;p&gt;Every boxing operation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allocates heap memory&lt;/li&gt;
&lt;li&gt;Triggers the Garbage Collector more frequently&lt;/li&gt;
&lt;li&gt;Copies data (twice — once to box, once to unbox)&lt;/li&gt;
&lt;li&gt;Adds CPU overhead from type checking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In hot paths — tight loops, high-frequency operations, large collections — boxing degrades performance significantly.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;The Classic Boxing Trap — ArrayList&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Old way — ArrayList boxes every int&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArrayList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Boxing happens 1,000,000 times&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ New way — List&amp;lt;T&amp;gt; avoids boxing entirely&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// No boxing&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; uses generics — no boxing required.&lt;br&gt;&lt;br&gt;
&lt;code&gt;ArrayList&lt;/code&gt; treats everything as &lt;code&gt;object&lt;/code&gt; — boxing on every insert.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Another Common Trap — Interfaces and Structs&lt;/strong&gt;
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IPrintable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPrintable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;IPrintable&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Boxing!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Assigning a struct to an interface causes boxing.&lt;br&gt;&lt;br&gt;
The struct is copied to the heap so it can be referenced as an interface.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Spotting Boxing at Runtime&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Boxing shows up as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increased GC collections (especially Gen0)&lt;/li&gt;
&lt;li&gt;Memory pressure in profilers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;System.Object&lt;/code&gt; allocations in heap snapshots&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use tools like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;dotMemory&lt;/strong&gt; (JetBrains)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BenchmarkDotNet&lt;/strong&gt; with memory diagnostics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visual Studio Diagnostic Tools&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GC.GetTotalMemory(false)&lt;/code&gt; for quick checks&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Real-World Scenario&lt;/strong&gt;
&lt;/h1&gt;
&lt;h3&gt;
  
  
  Scenario: Logging with string interpolation
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;101&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isActive&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ❌ Older pattern — potential boxing with format args&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User {0} active: {1}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Modern — string interpolation compiles efficiently&lt;/span&gt;
&lt;span class="s"&gt;$"User &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; active: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Best for hot paths — structured logging with no boxing via generics&lt;/span&gt;
&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User {UserId} active: {IsActive}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;ILogger&amp;lt;T&amp;gt;&lt;/code&gt; uses generic overloads to avoid boxing on primitive arguments.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Interview-Ready Summary&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Value types store data directly — assignment copies the value&lt;/li&gt;
&lt;li&gt;Reference types store a pointer — assignment shares the reference&lt;/li&gt;
&lt;li&gt;Stack = fast, limited, deterministic; Heap = larger, GC-managed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;struct&lt;/code&gt; is a value type; &lt;code&gt;class&lt;/code&gt; is a reference type&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;struct&lt;/code&gt; for small, immutable, short-lived data&lt;/li&gt;
&lt;li&gt;Boxing converts a value type to &lt;code&gt;object&lt;/code&gt; and allocates on the heap&lt;/li&gt;
&lt;li&gt;Unboxing copies the value back from the heap&lt;/li&gt;
&lt;li&gt;Boxing in loops or large collections silently destroys performance&lt;/li&gt;
&lt;li&gt;Generics (&lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;) were introduced specifically to eliminate boxing&lt;/li&gt;
&lt;li&gt;Assigning a struct to an interface triggers boxing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Value types hold their data directly and live on the stack by default, while reference types store a pointer to heap memory. Structs are value types best suited for small, immutable data. Boxing wraps a value type in a heap-allocated object — it's implicit, easy to miss, and expensive at scale. Generics eliminate boxing by preserving type information at compile time."&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;⭐ &lt;strong&gt;Add-On — Why This Matters More Now With &lt;code&gt;record struct&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;C# 10 introduced &lt;code&gt;record struct&lt;/code&gt; — a value type with built-in immutability and value equality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;Coordinate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Lat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Lon&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Coordinate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Coordinate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// True — value equality, no boxing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you the clean syntax of records without the heap allocation of reference-type records.&lt;br&gt;&lt;br&gt;
For high-performance scenarios where you want immutable data structures, &lt;code&gt;record struct&lt;/code&gt; is now the go-to choice.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>performance</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>IDisposable, Finalizers, and the Dispose Pattern — The Complete Guide for .NET Developers</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Mon, 02 Mar 2026 13:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/idisposable-finalizers-and-the-dispose-pattern-the-complete-guide-for-net-developers-4600</link>
      <guid>https://forem.com/libintombaby/idisposable-finalizers-and-the-dispose-pattern-the-complete-guide-for-net-developers-4600</guid>
      <description>

&lt;h1&gt;
  
  
  &lt;strong&gt;IDisposable, Finalizers, and the Dispose Pattern in .NET&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Memory management in .NET is automatic thanks to the Garbage Collector (GC). But GC only handles &lt;strong&gt;managed memory&lt;/strong&gt;. When your application interacts with &lt;strong&gt;unmanaged resources&lt;/strong&gt; — file handles, database connections, sockets, streams, OS handles — the GC cannot clean them up.&lt;/p&gt;

&lt;p&gt;That’s where &lt;code&gt;IDisposable&lt;/code&gt;, finalizers, and the Dispose Pattern come in.&lt;/p&gt;

&lt;p&gt;This guide explains how they work, why they exist, and how to implement them correctly in real-world .NET applications.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Why Do We Need IDisposable?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;GC cleans up &lt;strong&gt;managed objects&lt;/strong&gt;, but unmanaged resources live &lt;em&gt;outside&lt;/em&gt; the .NET runtime.&lt;/p&gt;

&lt;p&gt;Examples of unmanaged resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File handles
&lt;/li&gt;
&lt;li&gt;Network sockets
&lt;/li&gt;
&lt;li&gt;Database connections
&lt;/li&gt;
&lt;li&gt;OS handles
&lt;/li&gt;
&lt;li&gt;Native memory
&lt;/li&gt;
&lt;li&gt;GDI+ objects
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These must be released &lt;strong&gt;deterministically&lt;/strong&gt;, not “whenever GC runs.”&lt;/p&gt;

&lt;p&gt;&lt;code&gt;IDisposable&lt;/code&gt; gives you a way to clean up these resources immediately.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;What Is IDisposable?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;IDisposable&lt;/code&gt; defines a single method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IDisposable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling &lt;code&gt;Dispose()&lt;/code&gt; releases unmanaged resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;using&lt;/code&gt; statement ensures cleanup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// work with stream&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Dispose() is called automatically here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is deterministic cleanup — the resource is released &lt;em&gt;immediately&lt;/em&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;What Are Finalizers?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;finalizer&lt;/strong&gt; (also called a destructor) is a method that runs when the GC collects an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="nf"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// cleanup logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  But finalizers are expensive
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;They delay garbage collection
&lt;/li&gt;
&lt;li&gt;They require extra GC passes
&lt;/li&gt;
&lt;li&gt;They keep objects alive longer
&lt;/li&gt;
&lt;li&gt;They run on a background thread
&lt;/li&gt;
&lt;li&gt;Execution timing is unpredictable
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finalizers should be used &lt;strong&gt;only as a safety net&lt;/strong&gt;, not as the primary cleanup mechanism.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;The Dispose Pattern (The Correct Way)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;When your class holds unmanaged resources, implement the full Dispose Pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Standard implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ResourceHolder&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IDisposable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;_disposed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;GC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SuppressFinalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;disposing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_disposed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;disposing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Dispose managed resources&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Free unmanaged resources&lt;/span&gt;

        &lt;span class="n"&gt;_disposed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="nf"&gt;ResourceHolder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why this pattern?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Dispose(true)&lt;/code&gt; → clean managed + unmanaged resources
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Dispose(false)&lt;/code&gt; → clean unmanaged only (finalizer path)
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GC.SuppressFinalize&lt;/code&gt; → prevents finalizer from running unnecessarily
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures safe cleanup in all scenarios.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;When Should You Implement IDisposable?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Implement &lt;code&gt;IDisposable&lt;/code&gt; when your class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Directly holds unmanaged resources
&lt;/li&gt;
&lt;li&gt;Wraps a type that implements &lt;code&gt;IDisposable&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Uses OS handles
&lt;/li&gt;
&lt;li&gt;Uses native memory
&lt;/li&gt;
&lt;li&gt;Uses streams, DB connections, HttpClient, etc.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: wrapping a disposable object
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReportWriter&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IDisposable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;StreamWriter&lt;/span&gt; &lt;span class="n"&gt;_writer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ReportWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_writer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  &lt;strong&gt;Common Mistakes&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  ❌ Forgetting to call Dispose
&lt;/h3&gt;

&lt;p&gt;Leads to file locks, memory leaks, socket exhaustion.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Using finalizers unnecessarily
&lt;/h3&gt;

&lt;p&gt;Hurts performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Using &lt;code&gt;async void&lt;/code&gt; with disposable resources
&lt;/h3&gt;

&lt;p&gt;Exceptions become uncatchable.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Disposing objects you don’t own
&lt;/h3&gt;

&lt;p&gt;Only dispose what &lt;em&gt;your class created&lt;/em&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;SafeHandle — The Modern Way&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Instead of writing finalizers manually, .NET recommends using &lt;code&gt;SafeHandle&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyResource&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IDisposable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;SafeHandle&lt;/span&gt; &lt;span class="n"&gt;_handle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SafeFileHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_handle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No need for finalizers
&lt;/li&gt;
&lt;li&gt;Built-in reliability
&lt;/li&gt;
&lt;li&gt;Better performance
&lt;/li&gt;
&lt;li&gt;Less boilerplate
&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Async Dispose (&lt;code&gt;IAsyncDisposable&lt;/code&gt;)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;For async cleanup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyAsyncResource&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IAsyncDisposable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;ValueTask&lt;/span&gt; &lt;span class="nf"&gt;DisposeAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DisposeAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asynchronous streams
&lt;/li&gt;
&lt;li&gt;Network operations
&lt;/li&gt;
&lt;li&gt;Database connections
&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Real‑World Scenarios&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 1: File I/O&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;File handles must be released immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 2: Database connections&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Connection pools get exhausted if Dispose is not called.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 3: Network sockets&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Unreleased sockets cause port exhaustion.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 4: Interop with native libraries&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Unmanaged memory must be freed manually.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Interview‑Ready Summary&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;GC cleans &lt;strong&gt;managed memory&lt;/strong&gt;, not unmanaged resources
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IDisposable&lt;/code&gt; enables deterministic cleanup
&lt;/li&gt;
&lt;li&gt;Finalizers are a &lt;strong&gt;safety net&lt;/strong&gt;, not the primary cleanup mechanism
&lt;/li&gt;
&lt;li&gt;The Dispose Pattern ensures safe cleanup in all cases
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;using&lt;/code&gt; or &lt;code&gt;await using&lt;/code&gt; to guarantee disposal
&lt;/li&gt;
&lt;li&gt;Prefer &lt;code&gt;SafeHandle&lt;/code&gt; over manual finalizers
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“IDisposable exists because GC cannot clean unmanaged resources. Dispose provides deterministic cleanup, while finalizers act as a fallback. The Dispose Pattern ensures both managed and unmanaged resources are released safely.”&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>dotnet</category>
      <category>memorymanagement</category>
      <category>csharp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Async/Await in C# — A Deep Dive Into How Asynchronous Programming Really Works</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Sat, 28 Feb 2026 13:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/asyncawait-in-c-a-deep-dive-into-how-asynchronous-programming-really-works-3f01</link>
      <guid>https://forem.com/libintombaby/asyncawait-in-c-a-deep-dive-into-how-asynchronous-programming-really-works-3f01</guid>
      <description>

&lt;h1&gt;
  
  
  &lt;strong&gt;Async/Await in C#&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Asynchronous programming is one of the most important concepts in modern .NET development. Whether you're building APIs, background services, or UI applications, understanding &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; is essential for writing scalable, responsive, and high‑performance code.&lt;/p&gt;

&lt;p&gt;But many developers only know how to &lt;em&gt;use&lt;/em&gt; async/await — not how it actually works under the hood. This guide breaks down the mechanics, the patterns, the pitfalls, and the real-world scenarios that matter in interviews and production systems.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Why Asynchronous Programming Exists&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;The goal of async programming is simple:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Free up threads instead of blocking them.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Blocking = waste&lt;br&gt;&lt;br&gt;
Async = efficiency&lt;/p&gt;

&lt;p&gt;In a web server, every blocked thread reduces throughput.&lt;br&gt;&lt;br&gt;
In a UI app, blocking freezes the interface.&lt;/p&gt;

&lt;p&gt;Async/await solves this by allowing operations to &lt;em&gt;pause&lt;/em&gt; without blocking the thread.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;What &lt;code&gt;async&lt;/code&gt; Really Means&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Marking a method as &lt;code&gt;async&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows the use of &lt;code&gt;await&lt;/code&gt; inside the method
&lt;/li&gt;
&lt;li&gt;Automatically wraps the return type in a &lt;code&gt;Task&lt;/code&gt; or &lt;code&gt;Task&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Does &lt;strong&gt;not&lt;/strong&gt; make the method run on a background thread
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetNumberAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This method is still synchronous unless it contains an awaited asynchronous operation.&lt;/p&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;What &lt;code&gt;await&lt;/code&gt; Really Does&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;await&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; create a new thread.&lt;br&gt;&lt;br&gt;
It:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Starts an asynchronous operation
&lt;/li&gt;
&lt;li&gt;Returns control to the caller
&lt;/li&gt;
&lt;li&gt;Resumes the method when the operation completes
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetStringAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;While waiting for the network response:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The thread is returned to the thread pool
&lt;/li&gt;
&lt;li&gt;No blocking occurs
&lt;/li&gt;
&lt;li&gt;The method resumes when the response arrives
&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  &lt;strong&gt;Async/Await Under the Hood&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;When you write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;SomeOperationAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler transforms your method into a &lt;strong&gt;state machine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This state machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracks where execution paused
&lt;/li&gt;
&lt;li&gt;Resumes at the correct point
&lt;/li&gt;
&lt;li&gt;Handles exceptions
&lt;/li&gt;
&lt;li&gt;Handles return values
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why async/await feels synchronous but behaves asynchronously.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Task vs Task vs void&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Task&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Represents an asynchronous operation with no return value.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Task&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Represents an asynchronous operation that returns a value.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;void&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Only for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event handlers
&lt;/li&gt;
&lt;li&gt;Fire‑and‑forget operations (dangerous)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Never use &lt;code&gt;async void&lt;/code&gt; in business logic — you lose exception handling.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Common Mistake: Blocking Async Code&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetDataAsync&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// ❌ Deadlock risk&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetDataAsync&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// ❌ Deadlock risk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Blocking async code causes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deadlocks
&lt;/li&gt;
&lt;li&gt;Thread starvation
&lt;/li&gt;
&lt;li&gt;Performance issues
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always use &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;ConfigureAwait(false)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Used in library code to avoid capturing the synchronization context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;SomeOperationAsync&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ConfigureAwait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When to use it
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Class libraries
&lt;/li&gt;
&lt;li&gt;Background services
&lt;/li&gt;
&lt;li&gt;Anywhere except UI frameworks
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When NOT to use it
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;ASP.NET Core (no sync context)
&lt;/li&gt;
&lt;li&gt;UI apps (WPF, WinForms) unless you know what you're doing
&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Parallelism vs Asynchrony&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;These two are often confused.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Asynchrony&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Non‑blocking I/O&lt;br&gt;&lt;br&gt;
(Waiting without using a thread)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Parallelism&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Multiple threads executing simultaneously&lt;br&gt;&lt;br&gt;
(CPU‑bound work)&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: CPU‑bound
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;For&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;DoWork&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example: I/O‑bound
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  &lt;strong&gt;Real‑World Scenarios&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 1: Web API calling external services&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetWeather&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_weatherClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Async frees the thread to handle other requests.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 2: Database calls&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefaultAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;EF Core async methods prevent thread blocking.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 3: Background processing&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delays without blocking threads.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 4: File I/O&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllTextAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"log.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Async file operations scale better under load.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Interview‑Ready Summary&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;async&lt;/code&gt; enables &lt;code&gt;await&lt;/code&gt; and returns a Task
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;await&lt;/code&gt; pauses without blocking
&lt;/li&gt;
&lt;li&gt;Async/await uses compiler‑generated state machines
&lt;/li&gt;
&lt;li&gt;Never block async code with &lt;code&gt;.Result&lt;/code&gt; or &lt;code&gt;.Wait()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use async for I/O‑bound work
&lt;/li&gt;
&lt;li&gt;Use parallelism for CPU‑bound work
&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;async void&lt;/code&gt; except for event handlers
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Async/await allows non‑blocking I/O by returning threads to the pool while operations are in progress. The compiler generates a state machine that resumes execution when the awaited task completes. It improves scalability, especially in ASP.NET Core.”&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>dotnet</category>
      <category>async</category>
      <category>performance</category>
      <category>csharp</category>
    </item>
    <item>
      <title>SOLID Principles in C# — A Practical, Real‑World Guide for .NET Developers</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Thu, 26 Feb 2026 13:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/solid-principles-in-c-a-practical-real-world-guide-for-net-developers-49i2</link>
      <guid>https://forem.com/libintombaby/solid-principles-in-c-a-practical-real-world-guide-for-net-developers-49i2</guid>
      <description>

&lt;h2&gt;
  
  
  &lt;strong&gt;SOLID Principles in C#&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;SOLID is one of those topics that shows up in every senior .NET interview — and for good reason. These five principles help you write cleaner, more maintainable, and more scalable code. But the real value comes from understanding how to &lt;em&gt;apply&lt;/em&gt; them in real-world .NET systems.&lt;/p&gt;

&lt;p&gt;This guide breaks down each principle with simple definitions, C# examples, and practical scenarios you can use in interviews or production code.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;S — Single Responsibility Principle (SRP)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;A class should have one and only one reason to change.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What it means
&lt;/h3&gt;

&lt;p&gt;A class should do &lt;strong&gt;one thing&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Not “mostly one thing.”&lt;br&gt;&lt;br&gt;
Not “one thing plus a helper.”&lt;br&gt;&lt;br&gt;
Just one responsibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class handles &lt;strong&gt;business logic&lt;/strong&gt; and &lt;strong&gt;emailing&lt;/strong&gt; — two responsibilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real‑world scenario
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Logging mixed with business logic
&lt;/li&gt;
&lt;li&gt;Controllers doing validation + mapping + business logic
&lt;/li&gt;
&lt;li&gt;Services doing too much
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SRP makes your code testable and easier to maintain.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;O — Open/Closed Principle (OCP)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Software entities should be open for extension but closed for modification.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What it means
&lt;/h3&gt;

&lt;p&gt;You should be able to &lt;strong&gt;add new behavior&lt;/strong&gt; without &lt;strong&gt;changing existing code&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"CreditCard"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"PayPal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Crypto"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every new payment method requires modifying this class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IPaymentMethod&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Pay&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreditCard&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPaymentMethod&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Pay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PayPal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPaymentMethod&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Pay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPaymentMethod&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Pay&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real‑world scenario
&lt;/h3&gt;

&lt;p&gt;Adding new features without breaking existing ones — especially in enterprise systems.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;L — Liskov Substitution Principle (LSP)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Subclasses should be substitutable for their base classes.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What it means
&lt;/h3&gt;

&lt;p&gt;If class B inherits from class A, you should be able to use B &lt;strong&gt;anywhere&lt;/strong&gt; A is expected — without breaking behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Penguin&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Penguins can't fly"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This violates LSP — a Penguin is not a Bird in this model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FlyingBird&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Fly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Penguin&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real‑world scenario
&lt;/h3&gt;

&lt;p&gt;Inheritance hierarchies that break behavior or introduce exceptions.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;I — Interface Segregation Principle (ISP)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Clients should not be forced to depend on interfaces they do not use.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What it means
&lt;/h3&gt;

&lt;p&gt;Small, focused interfaces are better than large, bloated ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IWorker&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Work&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Eat&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Robots don’t eat.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IWorkable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Work&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IFeedable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Eat&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real‑world scenario
&lt;/h3&gt;

&lt;p&gt;Large service interfaces with 20+ methods — most implementations only use a few.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;D — Dependency Inversion Principle (DIP)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Depend on abstractions, not concrete implementations.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What it means
&lt;/h3&gt;

&lt;p&gt;High-level modules should not depend on low-level modules.&lt;br&gt;&lt;br&gt;
Both should depend on &lt;strong&gt;interfaces&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReportService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;FileLogger&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileLogger&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tightly coupled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReportService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ReportService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can inject:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FileLogger
&lt;/li&gt;
&lt;li&gt;DatabaseLogger
&lt;/li&gt;
&lt;li&gt;CloudLogger
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real‑world scenario
&lt;/h3&gt;

&lt;p&gt;Dependency Injection in ASP.NET Core is built entirely on DIP.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Putting SOLID Together — A Real .NET Example&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Imagine building an order processing system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SRP&lt;/strong&gt; → OrderService handles orders only
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OCP&lt;/strong&gt; → Add new payment methods without modifying existing code
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LSP&lt;/strong&gt; → Subclasses behave correctly when substituted
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ISP&lt;/strong&gt; → Interfaces are small and focused
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DIP&lt;/strong&gt; → Services depend on abstractions, not concrete classes
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leads to cleaner architecture, easier testing, and safer refactoring.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Interview‑Ready Summary&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SRP&lt;/strong&gt; → One responsibility
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OCP&lt;/strong&gt; → Extend, don’t modify
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LSP&lt;/strong&gt; → Subtypes must behave correctly
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ISP&lt;/strong&gt; → Small interfaces
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DIP&lt;/strong&gt; → Depend on abstractions
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strong interview answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“SOLID helps create maintainable, scalable, and testable systems. It reduces coupling, improves extensibility, and keeps code clean as the system grows.”&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  ⭐ &lt;strong&gt;Add‑On&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Where Did SOLID Come From? A Brief Origin Story&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;SOLID didn’t appear out of nowhere — it has a clear lineage in software engineering history.&lt;/p&gt;

&lt;p&gt;The principles were originally introduced by &lt;strong&gt;Robert C. Martin (Uncle Bob)&lt;/strong&gt;, one of the most influential figures in modern software craftsmanship. He coined the acronym &lt;strong&gt;SOLID&lt;/strong&gt; in the early 2000s to group together five existing object‑oriented design principles that had been discussed in academic and professional circles for years.&lt;/p&gt;

&lt;p&gt;The ideas themselves were heavily inspired by earlier work from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bertrand Meyer&lt;/strong&gt; (creator of Eiffel) — especially the Open/Closed Principle
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Barbara Liskov&lt;/strong&gt; — whose Liskov Substitution Principle became the “L” in SOLID
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tom DeMarco, Grady Booch, and others&lt;/strong&gt; — pioneers of structured and OO design
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SOLID gained massive popularity because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uncle Bob promoted it through books, talks, and the Agile movement
&lt;/li&gt;
&lt;li&gt;It aligned perfectly with Test‑Driven Development (TDD)
&lt;/li&gt;
&lt;li&gt;It helped teams build maintainable, scalable systems
&lt;/li&gt;
&lt;li&gt;It became a cornerstone of Clean Architecture and modern .NET design
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today, SOLID is considered foundational knowledge for senior developers, architects, and anyone building long‑lived enterprise systems.&lt;/p&gt;




</description>
      <category>dotnet</category>
      <category>cleanarchitecture</category>
      <category>csharp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Dependency Injection Lifetime for DbContext in .NET: Choosing the Right Scope</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Tue, 24 Feb 2026 13:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/dependency-injection-lifetime-for-dbcontext-in-net-choosing-the-right-scope-367f</link>
      <guid>https://forem.com/libintombaby/dependency-injection-lifetime-for-dbcontext-in-net-choosing-the-right-scope-367f</guid>
      <description>

&lt;h2&gt;
  
  
  &lt;strong&gt;Which DI Lifetime to Use for DbContext?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you’ve worked with Entity Framework Core, you’ve probably seen the classic interview question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What lifetime should you use for DbContext — Scoped, Transient, or Singleton?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The correct answer is &lt;strong&gt;Scoped&lt;/strong&gt;, but understanding &lt;em&gt;why&lt;/em&gt; is what separates a junior developer from a senior engineer.&lt;/p&gt;

&lt;p&gt;This guide explains the reasoning, the internals, and real-world scenarios so you can answer confidently in interviews and write safer, more scalable applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Is DbContext?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;DbContext&lt;/code&gt; represents a &lt;strong&gt;unit of work&lt;/strong&gt; and a &lt;strong&gt;session with the database&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracks changes
&lt;/li&gt;
&lt;li&gt;Manages entity states
&lt;/li&gt;
&lt;li&gt;Handles database connections
&lt;/li&gt;
&lt;li&gt;Executes queries
&lt;/li&gt;
&lt;li&gt;Saves changes
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because it tracks state, its lifetime matters.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;The Three DI Lifetimes in .NET&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before choosing the right one, here’s a quick refresher:&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Transient&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A new instance every time it’s requested.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Scoped&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One instance per HTTP request.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Singleton&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One instance for the entire application lifetime.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Why DbContext Should Be Scoped&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  ✔️ 1. DbContext is &lt;strong&gt;not thread-safe&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;ASP.NET Core handles multiple requests concurrently.&lt;br&gt;&lt;br&gt;
If you use a &lt;strong&gt;Singleton DbContext&lt;/strong&gt;, multiple threads will share the same instance.&lt;/p&gt;

&lt;p&gt;This leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Race conditions
&lt;/li&gt;
&lt;li&gt;Corrupted state
&lt;/li&gt;
&lt;li&gt;Random exceptions
&lt;/li&gt;
&lt;li&gt;Broken change tracking
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ✔️ 2. Scoped matches the &lt;strong&gt;unit-of-work pattern&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Each HTTP request represents a business operation.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating an order
&lt;/li&gt;
&lt;li&gt;Updating a profile
&lt;/li&gt;
&lt;li&gt;Processing a payment
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A scoped DbContext ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One context per operation
&lt;/li&gt;
&lt;li&gt;One transaction per request
&lt;/li&gt;
&lt;li&gt;Clean change tracking
&lt;/li&gt;
&lt;li&gt;Predictable behavior
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ✔️ 3. Scoped ensures &lt;strong&gt;proper connection management&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;DbContext opens and closes connections efficiently within the request scope.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Why NOT Transient?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Transient creates a new DbContext every time it’s injected.&lt;/p&gt;

&lt;p&gt;This causes:&lt;/p&gt;
&lt;h3&gt;
  
  
  ❌ Multiple DbContexts in the same request
&lt;/h3&gt;

&lt;p&gt;You may accidentally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query with one context
&lt;/li&gt;
&lt;li&gt;Save with another
&lt;/li&gt;
&lt;li&gt;Lose change tracking
&lt;/li&gt;
&lt;li&gt;Break transactions
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ❌ Hard-to-debug inconsistencies
&lt;/h3&gt;

&lt;p&gt;Different DbContexts don’t share state.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Why NOT Singleton?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Singleton is the worst possible choice.&lt;/p&gt;
&lt;h3&gt;
  
  
  ❌ DbContext is not thread-safe
&lt;/h3&gt;

&lt;p&gt;Multiple requests → shared instance → chaos.&lt;/p&gt;
&lt;h3&gt;
  
  
  ❌ Memory leaks
&lt;/h3&gt;

&lt;p&gt;The context keeps tracking more and more entities.&lt;/p&gt;
&lt;h3&gt;
  
  
  ❌ Stale data
&lt;/h3&gt;

&lt;p&gt;Long-lived DbContexts cache query results.&lt;/p&gt;
&lt;h3&gt;
  
  
  ❌ Broken transactions
&lt;/h3&gt;

&lt;p&gt;A single DbContext cannot manage multiple concurrent operations.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Real‑World Scenarios&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 1: Web API request&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;User updates their profile.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One request
&lt;/li&gt;
&lt;li&gt;One DbContext
&lt;/li&gt;
&lt;li&gt;One transaction
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use Scoped&lt;/strong&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 2: Background service&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A hosted service processes messages from a queue.&lt;/p&gt;

&lt;p&gt;Each message should have its own DbContext.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServiceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use Scoped inside a created scope&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 3: Console app&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Short-lived operations.&lt;/p&gt;

&lt;p&gt;Transient or Scoped both work, but Scoped is still preferred for consistency.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How to Register DbContext Correctly&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSqlServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This registers DbContext as &lt;strong&gt;Scoped by default&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Interview‑Ready Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;DbContext should be &lt;strong&gt;Scoped&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;DbContext is &lt;strong&gt;not thread-safe&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Scoped aligns with &lt;strong&gt;unit-of-work&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Singleton causes &lt;strong&gt;race conditions and memory leaks&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Transient causes &lt;strong&gt;multiple contexts per request&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A clean, senior-level answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“DbContext should be registered as Scoped because it represents a unit of work per request, is not thread-safe, and must not be shared across concurrent operations. Transient creates too many contexts, and Singleton causes concurrency issues and stale tracking.”&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>efcore</category>
      <category>architectural</category>
    </item>
    <item>
      <title>Understanding Garbage Collection (GC) in .NET — How It Works and When It Matters</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Sun, 22 Feb 2026 13:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/understanding-garbage-collection-gc-in-net-how-it-works-and-when-it-matters-47ik</link>
      <guid>https://forem.com/libintombaby/understanding-garbage-collection-gc-in-net-how-it-works-and-when-it-matters-47ik</guid>
      <description>

&lt;h2&gt;
  
  
  &lt;strong&gt;Garbage Collection (GC) in .NET&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Memory management is one of the most important concepts in .NET. Developers often say “the Garbage Collector handles memory for you,” but few can clearly explain &lt;em&gt;how&lt;/em&gt; it works, &lt;em&gt;why&lt;/em&gt; it exists, and &lt;em&gt;what you can do to work with it instead of against it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This guide breaks down .NET’s Garbage Collection (GC) in a simple, practical way — with definitions, diagrams, examples, and real-world scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Is Garbage Collection?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Garbage Collection (GC) is an automatic memory management system in .NET.&lt;br&gt;&lt;br&gt;
Its job is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allocate memory for new objects
&lt;/li&gt;
&lt;li&gt;Track which objects are still in use
&lt;/li&gt;
&lt;li&gt;Free memory for objects that are no longer needed
&lt;/li&gt;
&lt;li&gt;Prevent memory leaks
&lt;/li&gt;
&lt;li&gt;Reduce developer errors like dangling pointers
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short: &lt;strong&gt;GC keeps your application healthy by cleaning up unused objects automatically.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;How GC Works in .NET&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The .NET GC uses a &lt;strong&gt;generational, mark‑and‑compact&lt;/strong&gt; algorithm.&lt;/p&gt;

&lt;p&gt;Let’s break that down.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;1. Generations (Gen 0, Gen 1, Gen 2)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Objects are grouped into generations based on their lifetime.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Generation 0&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Newly created objects
&lt;/li&gt;
&lt;li&gt;Collected frequently
&lt;/li&gt;
&lt;li&gt;Fastest to clean
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Generation 1&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Surviving objects from Gen 0
&lt;/li&gt;
&lt;li&gt;Medium‑lived objects
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Generation 2&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Long‑lived objects
&lt;/li&gt;
&lt;li&gt;Large objects
&lt;/li&gt;
&lt;li&gt;Cleaned infrequently
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Why generations?
&lt;/h3&gt;

&lt;p&gt;Most objects die young.&lt;br&gt;&lt;br&gt;
So GC optimizes for that.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;2. Mark Phase&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;GC pauses the application briefly and &lt;strong&gt;marks&lt;/strong&gt; all objects that are still reachable.&lt;/p&gt;

&lt;p&gt;Reachable means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local variables
&lt;/li&gt;
&lt;li&gt;Static references
&lt;/li&gt;
&lt;li&gt;Objects referenced by other objects
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else is considered garbage.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;3. Compact Phase&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After marking, GC &lt;strong&gt;compacts&lt;/strong&gt; memory by moving surviving objects together.&lt;br&gt;&lt;br&gt;
This reduces fragmentation and improves performance.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;4. Large Object Heap (LOH)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Objects &amp;gt; 85 KB go to the &lt;strong&gt;Large Object Heap&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not compacted often (expensive to move large objects)
&lt;/li&gt;
&lt;li&gt;Can cause fragmentation
&lt;/li&gt;
&lt;li&gt;Avoid unnecessary large allocations
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;When Does GC Run?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;GC runs automatically when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory is low
&lt;/li&gt;
&lt;li&gt;Gen 0 fills up
&lt;/li&gt;
&lt;li&gt;The system is under pressure
&lt;/li&gt;
&lt;li&gt;You explicitly call &lt;code&gt;GC.Collect()&lt;/code&gt; (not recommended)
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Should You Call &lt;code&gt;GC.Collect()&lt;/code&gt;?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Almost never.&lt;/p&gt;

&lt;p&gt;Calling it manually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forces a full collection
&lt;/li&gt;
&lt;li&gt;Pauses your app
&lt;/li&gt;
&lt;li&gt;Hurts performance
&lt;/li&gt;
&lt;li&gt;Breaks GC’s optimization logic
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use it only in rare scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After a massive one‑time memory release
&lt;/li&gt;
&lt;li&gt;In controlled environments (e.g., game engines)
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;How to Work With GC (Best Practices)&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  ✔️ Use &lt;code&gt;using&lt;/code&gt; statements for disposable objects
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// work with stream&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This ensures deterministic cleanup.&lt;/p&gt;


&lt;h3&gt;
  
  
  ✔️ Avoid unnecessary large object allocations
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bigArray&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// Goes to LOH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Reuse buffers when possible.&lt;/p&gt;


&lt;h3&gt;
  
  
  ✔️ Prefer &lt;code&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Memory&amp;lt;T&amp;gt;&lt;/code&gt; for high-performance scenarios
&lt;/h3&gt;

&lt;p&gt;These avoid heap allocations.&lt;/p&gt;


&lt;h3&gt;
  
  
  ✔️ Avoid long-lived references
&lt;/h3&gt;

&lt;p&gt;If you keep references alive, GC cannot collect them.&lt;/p&gt;


&lt;h3&gt;
  
  
  ✔️ Use dependency injection wisely
&lt;/h3&gt;

&lt;p&gt;Singletons live for the entire app lifetime — avoid storing large objects inside them.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Real‑World Scenarios&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 1: Web API handling thousands of requests&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Short-lived objects → Gen 0&lt;br&gt;&lt;br&gt;
GC handles them efficiently.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 2: Image processing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Large byte arrays → LOH&lt;br&gt;&lt;br&gt;
Avoid repeated allocations; use pooling.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 3: Background services&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Long-lived services → Gen 2&lt;br&gt;&lt;br&gt;
Be careful with memory leaks.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Interview‑Ready Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GC automatically manages memory in .NET
&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;generational collection&lt;/strong&gt; (Gen 0, 1, 2)
&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;mark and compact&lt;/strong&gt; algorithm
&lt;/li&gt;
&lt;li&gt;LOH stores large objects
&lt;/li&gt;
&lt;li&gt;Avoid calling &lt;code&gt;GC.Collect()&lt;/code&gt; manually
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;using&lt;/code&gt;, pooling, and DI best practices
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This explanation shows you understand both the theory and the practical implications.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✅ &lt;strong&gt;Bonus thought&lt;/strong&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Is &lt;code&gt;IDisposable&lt;/code&gt; Related to Garbage Collection? Clearing the Confusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Many developers — especially those new to .NET — assume that &lt;code&gt;IDisposable&lt;/code&gt; is part of the Garbage Collector. It’s a common misunderstanding, but the two concepts solve &lt;em&gt;different&lt;/em&gt; problems.&lt;/p&gt;
&lt;h3&gt;
  
  
  Garbage Collection handles &lt;em&gt;managed memory&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;GC automatically frees memory for objects stored on the &lt;strong&gt;managed heap&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Examples:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Classes
&lt;/li&gt;
&lt;li&gt;Strings
&lt;/li&gt;
&lt;li&gt;Arrays
&lt;/li&gt;
&lt;li&gt;Delegates
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GC decides &lt;em&gt;when&lt;/em&gt; to clean them up.&lt;/p&gt;
&lt;h3&gt;
  
  
  IDisposable handles &lt;em&gt;unmanaged resources&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;IDisposable&lt;/code&gt; exists because GC &lt;strong&gt;cannot&lt;/strong&gt; clean up unmanaged resources, such as:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File handles
&lt;/li&gt;
&lt;li&gt;Database connections
&lt;/li&gt;
&lt;li&gt;Network sockets
&lt;/li&gt;
&lt;li&gt;OS handles
&lt;/li&gt;
&lt;li&gt;Streams
&lt;/li&gt;
&lt;li&gt;Native memory
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These require &lt;strong&gt;deterministic cleanup&lt;/strong&gt;, which is why we use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// work with stream&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;How they relate&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GC cleans up &lt;strong&gt;managed memory&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IDisposable&lt;/code&gt; cleans up &lt;strong&gt;unmanaged resources&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Finalizers (&lt;code&gt;~ClassName&lt;/code&gt;) act as a &lt;em&gt;safety net&lt;/em&gt;, but they are expensive
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;using&lt;/code&gt; statement ensures cleanup happens &lt;strong&gt;immediately&lt;/strong&gt;, not “whenever GC runs”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The rule of thumb&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;GC ≠ Dispose&lt;br&gt;&lt;br&gt;
GC frees memory&lt;br&gt;&lt;br&gt;
Dispose frees resources  &lt;/p&gt;

&lt;p&gt;This distinction is crucial in interviews and real-world systems.&lt;/p&gt;




</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>tutorial</category>
      <category>performance</category>
    </item>
    <item>
      <title>What the 'sealed' Keyword Means in C# — And When You Should Use It</title>
      <dc:creator>Libin Tom Baby</dc:creator>
      <pubDate>Fri, 20 Feb 2026 13:00:00 +0000</pubDate>
      <link>https://forem.com/libintombaby/what-the-sealed-keyword-means-in-c-and-when-you-should-use-it-572g</link>
      <guid>https://forem.com/libintombaby/what-the-sealed-keyword-means-in-c-and-when-you-should-use-it-572g</guid>
      <description>

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;code&gt;sealed&lt;/code&gt; Keyword in C#&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;sealed&lt;/code&gt; keyword is one of those C# features that developers see often but rarely think deeply about. It quietly influences inheritance, performance, and API design — especially in large systems and frameworks.&lt;/p&gt;

&lt;p&gt;This guide explains what &lt;code&gt;sealed&lt;/code&gt; does, why it exists, and when you should (and shouldn’t) use it, with practical examples and real-world scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Does &lt;code&gt;sealed&lt;/code&gt; Mean?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;sealed&lt;/code&gt; keyword &lt;strong&gt;prevents a class from being inherited&lt;/strong&gt; or &lt;strong&gt;prevents a virtual method from being overridden further&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can apply &lt;code&gt;sealed&lt;/code&gt; to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;class&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;method&lt;/strong&gt; (when overriding a virtual method)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;1. Sealed Classes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;sealed class cannot be inherited&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trying to inherit from it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomLogger&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Logger&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 
&lt;span class="c1"&gt;// ❌ Error: cannot derive from sealed type&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why seal a class?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To &lt;strong&gt;prevent misuse&lt;/strong&gt; through inheritance
&lt;/li&gt;
&lt;li&gt;To &lt;strong&gt;lock down behavior&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;To &lt;strong&gt;improve performance&lt;/strong&gt; (JIT optimizes sealed classes)
&lt;/li&gt;
&lt;li&gt;To &lt;strong&gt;protect API design&lt;/strong&gt; in libraries
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2. Sealed Methods&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You can also seal a &lt;strong&gt;method&lt;/strong&gt;, but only when overriding a virtual method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Implementation&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GrandChild&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Child&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 
    &lt;span class="c1"&gt;// ❌ Error: cannot override sealed method&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why seal a method?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To &lt;strong&gt;stop further overrides&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;To &lt;strong&gt;preserve behavior&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;To &lt;strong&gt;avoid breaking logic&lt;/strong&gt; in subclasses
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why Does &lt;code&gt;sealed&lt;/code&gt; Improve Performance?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When a class is sealed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The JIT compiler knows &lt;strong&gt;no subclass will override methods&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It can &lt;strong&gt;devirtualize&lt;/strong&gt; calls
&lt;/li&gt;
&lt;li&gt;It can &lt;strong&gt;inline&lt;/strong&gt; methods
&lt;/li&gt;
&lt;li&gt;It can &lt;strong&gt;optimize dispatch&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes sealed classes slightly faster, especially in tight loops or high-frequency calls.&lt;/p&gt;

&lt;p&gt;This is why many .NET framework classes (e.g., &lt;code&gt;String&lt;/code&gt;) are sealed.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Real‑World Scenarios&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 1: Utility classes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Utility classes like &lt;code&gt;Math&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt;, or &lt;code&gt;Path&lt;/code&gt; are sealed because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are not meant to be extended
&lt;/li&gt;
&lt;li&gt;Inheritance would cause confusion
&lt;/li&gt;
&lt;li&gt;Behavior must remain consistent
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 2: Preventing fragile inheritance&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you expose a class in a public API, consumers might inherit from it in unexpected ways.&lt;/p&gt;

&lt;p&gt;Sealing the class protects your design.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 3: Performance‑critical components&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;High-performance libraries often seal classes to allow JIT optimizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scenario 4: Sealing methods in a hierarchy&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You may want to allow inheritance but restrict certain behaviors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Move&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Move&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Birds fly&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now no subclass of &lt;code&gt;Bird&lt;/code&gt; can change how &lt;code&gt;Move()&lt;/code&gt; works.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;When NOT to Use &lt;code&gt;sealed&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When you expect developers to extend your class
&lt;/li&gt;
&lt;li&gt;When you’re building a framework that encourages inheritance
&lt;/li&gt;
&lt;li&gt;When sealing would limit testability (mocking frameworks often rely on inheritance)
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Interview‑Ready Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sealed&lt;/code&gt; prevents inheritance
&lt;/li&gt;
&lt;li&gt;Sealed classes = no subclassing
&lt;/li&gt;
&lt;li&gt;Sealed methods = no further overrides
&lt;/li&gt;
&lt;li&gt;Sealing improves performance via JIT optimizations
&lt;/li&gt;
&lt;li&gt;Use it to protect API design, prevent misuse, and optimize performance
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>beginners</category>
      <category>oop</category>
    </item>
  </channel>
</rss>
