<?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>DEV Community: Ahmed Shah</title>
    <description>The latest articles on DEV Community by Ahmed Shah (@ahmedshahjr).</description>
    <link>https://dev.to/ahmedshahjr</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F290153%2F2df0df8f-76fa-4a86-a709-8fef341fec5b.jpg</url>
      <title>DEV Community: Ahmed Shah</title>
      <link>https://dev.to/ahmedshahjr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahmedshahjr"/>
    <language>en</language>
    <item>
      <title>C# 14's field Keyword: Property Validation Without a Backing Field</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Sun, 11 Oct 2026 16:36:59 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/c-14s-field-keyword-property-validation-without-a-backing-field-6g5</link>
      <guid>https://dev.to/ahmedshahjr/c-14s-field-keyword-property-validation-without-a-backing-field-6g5</guid>
      <description>&lt;p&gt;In the previous post we looked at &lt;a href="https://dev.to/ahmedshahjr/should-you-migrate-to-net-10-today-an-honest-lts-decision-guide-5758"&gt;https://dev.to/ahmedshahjr/should-you-migrate-to-net-10-today-an-honest-lts-decision-guide-5758&lt;/a&gt; Once you target .NET 10, you also get &lt;strong&gt;C# 14&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This post starts a new 4-part series: &lt;strong&gt;C# 14 &amp;amp; Modern C# Deep Dive&lt;/strong&gt;. Part 1 is about one small keyword that we will use almost every day: &lt;strong&gt;&lt;code&gt;field&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post we will learn about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The old way: a private backing field just to add one check&lt;/li&gt;
&lt;li&gt;What the &lt;code&gt;field&lt;/code&gt; keyword is and how to enable it&lt;/li&gt;
&lt;li&gt;Before and after code, plus lazy and trim examples&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The rules and the three gotchas to know before you upgrade&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In C# 14, &lt;code&gt;field&lt;/code&gt; inside a property accessor means "the backing field the compiler made for this property".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can add &lt;strong&gt;validation&lt;/strong&gt; or &lt;strong&gt;normalization&lt;/strong&gt; to a property &lt;strong&gt;without declaring a private field&lt;/strong&gt; and without writing the &lt;code&gt;get&lt;/code&gt; body.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Watch out for three things: &lt;strong&gt;initializers skip the setter&lt;/strong&gt;, &lt;code&gt;field&lt;/code&gt; works &lt;strong&gt;only inside that property&lt;/strong&gt;, and an existing member named &lt;code&gt;field&lt;/code&gt; &lt;strong&gt;changes meaning&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The problem: a private field just to add one check
&lt;/h2&gt;

&lt;p&gt;Here is a property we have all written many times. We want a &lt;code&gt;Price&lt;/code&gt; that is never negative. An auto property (&lt;code&gt;{ get; set; }&lt;/code&gt;) can't do that, so we add a private field and write both accessors.&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;// Before/Product.cs&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FieldKeywordDemo.Before&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;Product&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;decimal&lt;/span&gt; &lt;span class="n"&gt;_price&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;Price&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_price&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;
            &lt;span class="p"&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;ArgumentOutOfRangeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Price must not be negative."&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;ApplyDiscount&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;percent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Compiles fine, but skips the check in the setter&lt;/span&gt;
        &lt;span class="n"&gt;_price&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;_price&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;percent&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="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 works, but notice two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We wrote a field and a &lt;code&gt;get&lt;/code&gt; body only to add &lt;strong&gt;one&lt;/strong&gt; line of logic to the setter.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_price&lt;/code&gt; is visible to the &lt;strong&gt;whole class&lt;/strong&gt;. &lt;code&gt;ApplyDiscount&lt;/code&gt; writes to it directly, so a 150% discount gives a negative price, and the setter never runs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-14.0/field-keyword" rel="noopener noreferrer"&gt;feature specification&lt;/a&gt; names this second point too: the backing field leaks into the rest of the type, and code can bypass the accessors by accident.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is the &lt;code&gt;field&lt;/code&gt; keyword?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;field&lt;/code&gt;&lt;/strong&gt; is a &lt;strong&gt;contextual keyword&lt;/strong&gt; added in &lt;a href="https://learn.microsoft.com/dotnet/csharp/whats-new/csharp-14" rel="noopener noreferrer"&gt;C# 14&lt;/a&gt;. Inside a property accessor, it refers to the &lt;strong&gt;backing field that the compiler creates&lt;/strong&gt; for that property. You don't declare it, and you don't name it.&lt;/p&gt;

&lt;p&gt;A property that uses &lt;code&gt;field&lt;/code&gt; is called a &lt;strong&gt;field-backed property&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;How to enable it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Target &lt;strong&gt;&lt;code&gt;net10.0&lt;/code&gt;&lt;/strong&gt;. The &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/language-versioning" rel="noopener noreferrer"&gt;default language version&lt;/a&gt; for .NET 10 is C# 14, so there is nothing else to set.&lt;/li&gt;
&lt;li&gt;You need the &lt;strong&gt;.NET 10 SDK&lt;/strong&gt; or &lt;strong&gt;Visual Studio 2026&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;field&lt;/code&gt; was a &lt;strong&gt;preview&lt;/strong&gt; feature in &lt;a href="https://learn.microsoft.com/dotnet/csharp/whats-new/csharp-13#the-field-keyword" rel="noopener noreferrer"&gt;C# 13&lt;/a&gt;. In C# 14 it is a regular, supported feature. Microsoft says using a newer C# version than your target framework's default is &lt;strong&gt;unsupported&lt;/strong&gt;, so don't set &lt;code&gt;LangVersion&lt;/code&gt; to 14 on a .NET 8 project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Before and after
&lt;/h2&gt;

&lt;p&gt;Here is the same &lt;code&gt;Product&lt;/code&gt; with &lt;code&gt;field&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;// After/Product.cs&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FieldKeywordDemo.After&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;Product&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;Price&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;
            &lt;span class="p"&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;ArgumentOutOfRangeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Price must not be negative."&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;ApplyDiscount&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;percent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// There is no private field to reach, so this goes through the setter&lt;/span&gt;
        &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;percent&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="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;What changed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No &lt;code&gt;_price&lt;/code&gt; field.&lt;/strong&gt; The compiler creates the backing field for us.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;get;&lt;/code&gt; stays automatic.&lt;/strong&gt; We mix an auto accessor (&lt;code&gt;get;&lt;/code&gt;) with a full accessor (&lt;code&gt;set =&amp;gt; ...&lt;/code&gt;). Before C# 14 this was not allowed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The check can't be skipped from other methods.&lt;/strong&gt; &lt;code&gt;ApplyDiscount&lt;/code&gt; must use &lt;code&gt;Price&lt;/code&gt;, so the setter always runs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Per property, we remove one field declaration and one hand-written accessor. For a class with many validated properties, that adds up.&lt;/p&gt;
&lt;h2&gt;
  
  
  Two more everyday patterns
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Trim and normalize input
&lt;/h3&gt;

&lt;p&gt;Emails, usernames and codes often need cleaning before we store them. This pattern is from the &lt;a href="https://learn.microsoft.com/dotnet/csharp/whats-new/csharp-14" rel="noopener noreferrer"&gt;What's new in C# 14&lt;/a&gt; page:&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;// After/Customer.cs&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FieldKeywordDemo.After&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;Customer&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;Email&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;()?.&lt;/span&gt;&lt;span class="nf"&gt;ToLowerInvariant&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&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;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&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 &lt;code&gt;= string.Empty&lt;/code&gt; initializer gives the backing field a start value, so the nullable checker is happy. (More on initializers below, because they have a catch.)&lt;/p&gt;
&lt;h3&gt;
  
  
  Lazy loading
&lt;/h3&gt;

&lt;p&gt;A get-only or expression-bodied property can also use &lt;code&gt;field&lt;/code&gt;. With &lt;code&gt;??=&lt;/code&gt;, the value is created on first read and then 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="c1"&gt;// After/CurrencyService.cs&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FieldKeywordDemo.After&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;CurrencyService&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="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;Currencies&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="p"&gt;??=&lt;/span&gt; &lt;span class="nf"&gt;LoadCurrencies&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;static&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;LoadCurrencies&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="s"&gt;"Loading currencies..."&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="s"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"GBP"&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;Let's run the demo and see the results:&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;// Program.cs&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;FieldKeywordDemo.After&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="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100m&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyDiscount&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="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;$"Price after discount: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&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;Customer&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="s"&gt;"  Ahmed@Example.COM "&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;$"Email: '&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;customer&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="s"&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;service&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;CurrencyService&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;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Currencies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&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;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Currencies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "Loading..." prints only once&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArgumentOutOfRangeException&lt;/span&gt; &lt;span class="n"&gt;ex&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;ex&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Price after discount: 90
Email: 'ahmed@example.com'
Loading currencies...
3
3
Price must not be negative. (Parameter 'value')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As you can see, "Loading currencies..." prints only once, and the 150% discount now throws instead of saving a negative price.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;field ??= ...&lt;/code&gt; is &lt;strong&gt;not thread-safe&lt;/strong&gt;. If two threads read the property at the same time, &lt;code&gt;LoadCurrencies&lt;/code&gt; can run twice. For shared objects (singletons in ASP.NET Core, for example), use the &lt;a href="https://learn.microsoft.com/dotnet/framework/performance/lazy-initialization" rel="noopener noreferrer"&gt;&lt;code&gt;Lazy&lt;/code&gt; type&lt;/a&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The rules you need to know
&lt;/h2&gt;

&lt;p&gt;From the &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/field" rel="noopener noreferrer"&gt;language reference&lt;/a&gt; and the &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-14.0/field-keyword" rel="noopener noreferrer"&gt;feature specification&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mix and match accessors.&lt;/strong&gt; &lt;code&gt;{ get; set =&amp;gt; ... }&lt;/code&gt;, &lt;code&gt;{ get =&amp;gt; ...; set; }&lt;/code&gt; and two full accessors all work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get-only and expression-bodied&lt;/strong&gt; properties can use &lt;code&gt;field&lt;/code&gt; (like the lazy example).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;{ set; }&lt;/code&gt; alone is still not allowed&lt;/strong&gt;, same as before.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;field&lt;/code&gt; works only in property accessors.&lt;/strong&gt; It is not a keyword in indexers or event accessors, and other methods in the class can't see the backing field.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;nameof(value)&lt;/code&gt;, not &lt;code&gt;nameof(field)&lt;/code&gt;,&lt;/strong&gt; in exceptions. &lt;code&gt;nameof(field)&lt;/code&gt; doesn't compile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Field-targeted attributes&lt;/strong&gt; work: &lt;code&gt;[field: SomeAttribute]&lt;/code&gt; goes on the hidden backing field, as with auto properties.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Gotcha 1: initializers don't call the setter
&lt;/h2&gt;

&lt;p&gt;A property initializer writes &lt;strong&gt;directly to the backing field&lt;/strong&gt;. The setter does &lt;strong&gt;not&lt;/strong&gt; run.&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;// After/Settings.cs&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FieldKeywordDemo.After&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;Settings&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;bool&lt;/span&gt; &lt;span class="n"&gt;HasChanges&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;private&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;string&lt;/span&gt; &lt;span class="n"&gt;Theme&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="n"&gt;field&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;HasChanges&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="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"light"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// sets the backing field only, HasChanges stays false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Often this is what we want: the default value should not count as a "change". But if your setter &lt;strong&gt;validates&lt;/strong&gt;, the initializer value is &lt;strong&gt;not validated&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want the setter to run for the start value, assign it in the &lt;strong&gt;constructor&lt;/strong&gt; instead. A constructor assignment calls the setter.&lt;/p&gt;
&lt;h2&gt;
  
  
  Gotcha 2: a member already named &lt;code&gt;field&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This is the &lt;a href="https://learn.microsoft.com/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2010" rel="noopener noreferrer"&gt;breaking change&lt;/a&gt; to check when you upgrade. If your class already has a member called &lt;code&gt;field&lt;/code&gt;, then inside a property accessor the word &lt;code&gt;field&lt;/code&gt; now means the &lt;strong&gt;backing field&lt;/strong&gt;, not your member.&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;// Legacy/Sensor.cs&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FieldKeywordDemo.Legacy&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;Sensor&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;double&lt;/span&gt; &lt;span class="n"&gt;field&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="c1"&gt;// an old member, named "field" by chance&lt;/span&gt;

    &lt;span class="c1"&gt;// C# 14: warning CS9258. This now reads a NEW backing field, not the member above.&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;Reading&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Fix: say which one you mean (or rename the member)&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;ReadingFixed&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// or @field&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Building this sample with the .NET 10 SDK gives:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Legacy\Sensor.cs(8,30): warning CS9258: In language version 14.0, the 'field' keyword binds to a synthesized backing field for the property. To avoid generating a synthesized backing field, and to refer to the existing member, use 'this.field' or '@field' instead.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The compiler gives warning &lt;strong&gt;CS9258&lt;/strong&gt; when &lt;code&gt;field&lt;/code&gt; would have meant something else in C# 13. &lt;strong&gt;Don't ignore it&lt;/strong&gt;: the code still compiles, but it reads a different value.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;local variable&lt;/strong&gt; named &lt;code&gt;field&lt;/code&gt; inside an accessor is now error &lt;strong&gt;CS9272&lt;/strong&gt;. Rename it or use &lt;code&gt;@field&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The cleanest fix is to &lt;strong&gt;rename&lt;/strong&gt; the old member.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; before upgrading a big solution, search for the word &lt;code&gt;field&lt;/code&gt; used as a name. It is rare, but generated code and old DTOs sometimes have it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  When to keep an explicit backing field
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;field&lt;/code&gt; doesn't replace every private field. Here is a simple way to decide:&lt;br&gt;
&lt;/p&gt;
&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[Does the property need any logic?] -- No --&amp;gt; B[Auto property: get; set;]
    A -- Yes --&amp;gt; C{Do other methods need&amp;lt;br/&amp;gt;the raw value, not the property?}
    C -- Yes --&amp;gt; D[Keep an explicit private field]
    C -- No --&amp;gt; E{Lazy value read by&amp;lt;br/&amp;gt;many threads?}
    E -- Yes --&amp;gt; F[Use the Lazy type]
    E -- No --&amp;gt; G[Use the field keyword]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Keep an explicit field when another method must &lt;strong&gt;reset or read the raw value&lt;/strong&gt; without going through the property (for example, a &lt;code&gt;Clear()&lt;/code&gt; method that bypasses validation on purpose). The &lt;code&gt;field&lt;/code&gt; keyword can't help there.&lt;/p&gt;
&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;field&lt;/code&gt; gives you the &lt;strong&gt;compiler-made backing field&lt;/strong&gt; inside a property accessor, in &lt;strong&gt;C# 14 / .NET 10&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use it for &lt;strong&gt;validation&lt;/strong&gt;, &lt;strong&gt;normalization&lt;/strong&gt; and &lt;strong&gt;simple lazy loading&lt;/strong&gt;, without a private field.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initializers skip the setter&lt;/strong&gt;; constructor assignments don't.&lt;/li&gt;
&lt;li&gt;Fix &lt;strong&gt;CS9258&lt;/strong&gt; warnings with &lt;code&gt;this.field&lt;/code&gt;, &lt;code&gt;@field&lt;/code&gt; or a rename.&lt;/li&gt;
&lt;li&gt;Keep an explicit field when other methods need the raw value, and use the &lt;code&gt;Lazy&lt;/code&gt; type for thread-safe lazy loading.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a small demo for learning, not a full guide to every rule. The &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-14.0/field-keyword" rel="noopener noreferrer"&gt;feature specification&lt;/a&gt; covers structs, nullability and overrides in detail.&lt;/p&gt;

&lt;p&gt;The sample code is on GitHub:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ahmedshahjr" rel="noopener noreferrer"&gt;
        ahmedshahjr
      &lt;/a&gt; / &lt;a href="https://github.com/ahmedshahjr/Articles" rel="noopener noreferrer"&gt;
        Articles
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Direct link to the sample folder: &lt;a href="https://github.com/ahmedshahjr/Articles/tree/main/csharp-14-field-keyword" rel="noopener noreferrer"&gt;csharp-14-field-keyword&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next part (Thursday, October 15) we will look at &lt;strong&gt;Extension Members in C# 14&lt;/strong&gt;: extension properties are finally here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you have a class in your codebase where &lt;code&gt;field&lt;/code&gt; would remove a backing field today, or do you prefer to keep the explicit field?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>programming</category>
    </item>
    <item>
      <title>Should You Migrate to .NET 10 Today? An Honest LTS Decision Guide</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Sun, 11 Oct 2026 14:43:43 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/should-you-migrate-to-net-10-today-an-honest-lts-decision-guide-5758</link>
      <guid>https://dev.to/ahmedshahjr/should-you-migrate-to-net-10-today-an-honest-lts-decision-guide-5758</guid>
      <description>&lt;p&gt;&lt;strong&gt;.NET 8&lt;/strong&gt; and &lt;strong&gt;.NET 9&lt;/strong&gt; both reach end of support on &lt;strong&gt;November 10, 2026&lt;/strong&gt;. That is about five weeks from today.&lt;/p&gt;

&lt;p&gt;Many of us still run services on .NET 8. It was the safe &lt;strong&gt;LTS&lt;/strong&gt; choice, and it worked well. So the real question now is not "should we move?" but "how fast, and to which version?"&lt;/p&gt;

&lt;p&gt;In this post we will learn about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The dates that matter, from Microsoft's own support policy&lt;/li&gt;
&lt;li&gt;What "end of support" really means for your apps on Azure&lt;/li&gt;
&lt;li&gt;A simple decision guide: migrate now, migrate soon, or wait&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The migration steps we follow, and the pitfalls to watch for&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.NET 10 is LTS&lt;/strong&gt; and is supported until &lt;strong&gt;November 14, 2028&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.NET 8 (LTS) and .NET 9 (STS)&lt;/strong&gt; end on the &lt;strong&gt;same day&lt;/strong&gt;: November 10, 2026.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For most production services, move to &lt;strong&gt;.NET 10 now&lt;/strong&gt;. Do not wait for .NET 11.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The dates that matter
&lt;/h2&gt;

&lt;p&gt;Here are the dates from the &lt;a href="https://dotnet.microsoft.com/platform/support/policy/dotnet-core" rel="noopener noreferrer"&gt;official .NET support policy&lt;/a&gt; (last updated September 8, 2026):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Released&lt;/th&gt;
&lt;th&gt;End of support&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;.NET 8&lt;/td&gt;
&lt;td&gt;LTS&lt;/td&gt;
&lt;td&gt;Nov 14, 2023&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Nov 10, 2026&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.NET 9&lt;/td&gt;
&lt;td&gt;STS&lt;/td&gt;
&lt;td&gt;Nov 12, 2024&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Nov 10, 2026&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.NET 10&lt;/td&gt;
&lt;td&gt;LTS&lt;/td&gt;
&lt;td&gt;Nov 11, 2025&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Nov 14, 2028&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.NET 11&lt;/td&gt;
&lt;td&gt;STS&lt;/td&gt;
&lt;td&gt;Nov 2026 (RC1 out now)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; .NET 9 was first planned to end in May 2026. During its life, Microsoft extended &lt;strong&gt;STS&lt;/strong&gt; support from 18 to &lt;strong&gt;24 months&lt;/strong&gt;. That is why .NET 8 and .NET 9 now end together.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;LTS&lt;/strong&gt; means Long Term Support (three years). &lt;strong&gt;STS&lt;/strong&gt; means Standard Term Support (now two years). The quality of both is the same. Only the support length is different.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "end of support" really means
&lt;/h2&gt;

&lt;p&gt;Your app will &lt;strong&gt;not&lt;/strong&gt; stop on November 11. It keeps running.&lt;/p&gt;

&lt;p&gt;But after that date:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No more &lt;strong&gt;security patches&lt;/strong&gt; for that runtime&lt;/li&gt;
&lt;li&gt;No Microsoft support if something breaks&lt;/li&gt;
&lt;li&gt;Security scanners and audits start to flag it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On &lt;strong&gt;Azure App Service&lt;/strong&gt;, apps on an old runtime keep running, but App Service &lt;a href="https://learn.microsoft.com/azure/app-service/language-support-policy" rel="noopener noreferrer"&gt;can't give security patches or support&lt;/a&gt; for that runtime after its end-of-support date.&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;Azure Functions&lt;/strong&gt;, check two things. .NET 8 and .NET 9 workers end on the same date. And the &lt;strong&gt;in-process model&lt;/strong&gt; for .NET Functions also &lt;a href="https://learn.microsoft.com/lifecycle/end-of-support/end-of-support-2026" rel="noopener noreferrer"&gt;ends support on November 10, 2026&lt;/a&gt;. If you still use in-process Functions, plan the move to the &lt;strong&gt;isolated worker model&lt;/strong&gt; together with the version upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision guide
&lt;/h2&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[Service on .NET 8 or 9] --&amp;gt; B{Is it in production&amp;lt;br/&amp;gt;and still maintained?}
    B -- No, retiring soon --&amp;gt; W[Fine to wait.&amp;lt;br/&amp;gt;Retire it, or isolate it]
    B -- Yes --&amp;gt; C{Do all key packages&amp;lt;br/&amp;gt;support .NET 10?}
    C -- Yes --&amp;gt; N[Migrate now to .NET 10]
    C -- Not yet --&amp;gt; S[Migrate soon.&amp;lt;br/&amp;gt;Track the blocker, upgrade the rest]
    N --&amp;gt; T[Target .NET 10 LTS,&amp;lt;br/&amp;gt;not .NET 11 STS]
    S --&amp;gt; T&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Migrate now
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The service is in production and you will keep changing it.&lt;/li&gt;
&lt;li&gt;It faces the internet, or it handles payments or personal data.&lt;/li&gt;
&lt;li&gt;Your main packages (EF Core, your message bus client, your auth library) already support .NET 10.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Migrate soon (but start this week)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;One important third-party package is not ready yet. Upgrade everything else, and keep a short list of blockers.&lt;/li&gt;
&lt;li&gt;You have many microservices. Start with one small, low-risk service and learn from it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  It's fine to wait
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The app will be &lt;strong&gt;retired soon&lt;/strong&gt;, and it is not exposed to the internet.&lt;/li&gt;
&lt;li&gt;It is a &lt;strong&gt;.NET Framework&lt;/strong&gt; app. That is a different support track and a different (bigger) migration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be honest with this last group. "We will retire it next year" often becomes three more years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why .NET 10 and not .NET 11?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;.NET 11&lt;/strong&gt; ships in November 2026, at .NET Conf (November 10 to 13). It is an &lt;strong&gt;STS&lt;/strong&gt; release.&lt;/p&gt;

&lt;p&gt;So why not wait and jump straight to .NET 11?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;.NET 11 GA arrives on the same day .NET 8 support ends.&lt;/strong&gt; Waiting leaves no buffer for testing.&lt;/li&gt;
&lt;li&gt;Your packages need time to support a new version. .NET 10 has had almost a year.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your team likes the newest features and upgrades every year, .NET 11 is a fine next step &lt;strong&gt;after&lt;/strong&gt; you are on .NET 10. Going 8 to 10 now, then 10 to 11 later, is a much smaller jump each time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step-by-step migration
&lt;/h2&gt;

&lt;p&gt;These are the steps we follow for one service. The sample config is in my repo (link at the end).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install the SDK and pin it with global.json
&lt;/h3&gt;

&lt;p&gt;Install the latest &lt;a href="https://dotnet.microsoft.com/download/dotnet/10.0" rel="noopener noreferrer"&gt;.NET 10 SDK&lt;/a&gt;. Then pin it, so every developer and the CI pipeline use the same SDK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;global.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sdk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10.0.100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rollForward"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"latestFeature"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;rollForward: latestFeature&lt;/code&gt; lets the build use a newer 10.0 SDK feature band if one is installed, &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Change the target framework in one place
&lt;/h3&gt;

&lt;p&gt;If you have many projects, put the target framework in &lt;strong&gt;Directory.Build.props&lt;/strong&gt; at the solution root. Then one line upgrades every project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Directory.Build.props --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Project&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net10.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;CheckSdkVulnerabilities&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/CheckSdkVulnerabilities&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; remove &lt;code&gt;&amp;lt;TargetFramework&amp;gt;&lt;/code&gt; from each &lt;code&gt;.csproj&lt;/code&gt;, or it will override this value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;CheckSdkVulnerabilities&lt;/code&gt; makes the build warn when the SDK you build with has known vulnerabilities (&lt;strong&gt;NETSDK1238&lt;/strong&gt;) or is end of life (&lt;strong&gt;NETSDK1239&lt;/strong&gt;). The check arrives with the .NET 11 SDK (Preview 5 and later); the .NET 10 SDK ignores the property, so today it does nothing. It is a cheap safety net for the next migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Update the Microsoft packages
&lt;/h3&gt;

&lt;p&gt;Update every &lt;code&gt;Microsoft.*&lt;/code&gt; package that follows the runtime version (ASP.NET Core, EF Core, Extensions) to &lt;strong&gt;10.0.x&lt;/strong&gt;. Then check what else is outdated or vulnerable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# from the solution folder&lt;/span&gt;
dotnet list package &lt;span class="nt"&gt;--outdated&lt;/span&gt;
dotnet list package &lt;span class="nt"&gt;--vulnerable&lt;/span&gt; &lt;span class="nt"&gt;--include-transitive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Read the breaking changes (really)
&lt;/h3&gt;

&lt;p&gt;Microsoft keeps a full list of &lt;a href="https://learn.microsoft.com/dotnet/core/compatibility/10" rel="noopener noreferrer"&gt;breaking changes in .NET 10&lt;/a&gt;. For microservices, these are the ones I would check first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Default .NET container images use Ubuntu&lt;/strong&gt; (not Debian). If your Dockerfile runs &lt;code&gt;apt-get&lt;/code&gt; or depends on OS packages, test it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;System.Linq.AsyncEnumerable&lt;/code&gt; is now in the core libraries.&lt;/strong&gt; If you use the &lt;code&gt;System.Linq.Async&lt;/code&gt; package, you can get conflicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;BackgroundService&lt;/code&gt; runs all of &lt;code&gt;ExecuteAsync&lt;/code&gt; as a Task.&lt;/strong&gt; Check workers that did blocking work before their first &lt;code&gt;await&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Null values are preserved in configuration.&lt;/strong&gt; Check options classes that relied on nulls being dropped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;dotnet restore&lt;/code&gt; audits transitive packages.&lt;/strong&gt; Your build may show new vulnerability warnings, which is a good thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also read &lt;a href="https://learn.microsoft.com/aspnet/core/breaking-changes/10/overview" rel="noopener noreferrer"&gt;ASP.NET Core 10 breaking changes&lt;/a&gt; and EF Core 10 breaking changes if you use them.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Update the Docker base images
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Dockerfile&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mcr.microsoft.com/dotnet/sdk:10.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet publish ./src/OrderService/OrderService.csproj &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;-o&lt;/span&gt; /app

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mcr.microsoft.com/dotnet/aspnet:10.0&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app .&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["dotnet", "OrderService.dll"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Update the CI pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/build.yml (only the setup step)&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-dotnet@v4&lt;/span&gt;  
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;global-json-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;global.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reading the version from &lt;code&gt;global.json&lt;/code&gt; means you change the SDK in one place only.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Update the Azure runtime setting
&lt;/h3&gt;

&lt;p&gt;For &lt;strong&gt;App Service on Linux&lt;/strong&gt;, change the stack to .NET 10:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az webapp config &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;app-name&amp;gt; &lt;span class="nt"&gt;--resource-group&lt;/span&gt; &amp;lt;rg-name&amp;gt; &lt;span class="nt"&gt;--linux-fx-version&lt;/span&gt; &lt;span class="s2"&gt;"DOTNETCORE|10.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;strong&gt;Azure Functions&lt;/strong&gt;, move to the &lt;strong&gt;isolated worker model&lt;/strong&gt; first if you are still in-process, then target &lt;code&gt;net10.0&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Run the tests, then deploy one service first
&lt;/h3&gt;

&lt;p&gt;Run all tests. Then deploy &lt;strong&gt;one&lt;/strong&gt; small service to a test environment and watch logs and metrics for a day before moving the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should a tool do this for me?
&lt;/h2&gt;

&lt;p&gt;Microsoft now recommends &lt;strong&gt;GitHub Copilot app modernization&lt;/strong&gt; for upgrades. It analyzes your solution, writes an upgrade plan, and commits each change so you can review or roll it back.&lt;/p&gt;

&lt;p&gt;The older &lt;strong&gt;.NET Upgrade Assistant&lt;/strong&gt; is &lt;a href="https://learn.microsoft.com/dotnet/core/porting/" rel="noopener noreferrer"&gt;officially deprecated&lt;/a&gt;. Use it only if you can't use the new agent.&lt;/p&gt;

&lt;p&gt;My honest view: a tool can do the boring edits. But you still need to read the breaking changes and test your own service. The tool doesn't know your production traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;.NET 8 and .NET 9 both end on &lt;strong&gt;November 10, 2026&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;.NET 10 (LTS, until November 14, 2028)&lt;/strong&gt; is the safe target for most services.&lt;/li&gt;
&lt;li&gt;Waiting for .NET 11 leaves you no testing buffer.&lt;/li&gt;
&lt;li&gt;Pin the SDK with &lt;code&gt;global.json&lt;/code&gt;, set the target framework in one place, and &lt;strong&gt;read the breaking changes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Start with one small service, then move the rest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a practical guide, not a full list of every change. Always check the official docs for your own stack.&lt;/p&gt;

&lt;p&gt;The sample config is on GitHub:&lt;br&gt;
&lt;a href="https://github.com/ahmedshahjr/Articles/tree/main/should-you-migrate-to-dotnet-10" rel="noopener noreferrer"&gt;https://github.com/ahmedshahjr/Articles/tree/main/should-you-migrate-to-dotnet-10&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Direct link to the sample folder: &lt;br&gt;
In the next post we will look at the new &lt;strong&gt;C# 14 &lt;code&gt;field&lt;/code&gt; keyword&lt;/strong&gt; and how it removes a lot of property boilerplate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which .NET version are your services running today, and what is the one thing blocking your move to .NET 10?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>azure</category>
      <category>beginners</category>
    </item>
    <item>
      <title>MIDDLEWARE BEST PRACTICES 💪</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Tue, 02 Sep 2025 17:17:53 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/middleware-best-practices-4k3b</link>
      <guid>https://dev.to/ahmedshahjr/middleware-best-practices-4k3b</guid>
      <description>&lt;p&gt;MIDDLEWARE BEST PRACTICES 💪✅ Keep middleware focused (single responsibility)✅ Order matters - plan your pipeline✅ Use built-in before custom✅ Always call next() or terminate✅ Handle exceptions gracefully&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fle0tw43oyr8y91z5yipa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fle0tw43oyr8y91z5yipa.png" alt=" " width="800" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb99lkbd1x6u62fllf0dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb99lkbd1x6u62fllf0dg.png" alt=" " width="800" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27w8ixi96qpfszvyv0x9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27w8ixi96qpfszvyv0x9.png" alt=" " width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznq0waan4glpf8aih6cd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznq0waan4glpf8aih6cd.png" alt=" " width="800" height="879"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhhr2nrnmvz0jh05j3ho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhhr2nrnmvz0jh05j3ho.png" alt=" " width="800" height="676"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu46uf5j5dc1nwou301x9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu46uf5j5dc1nwou301x9.png" alt=" " width="800" height="804"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ry8414hqox57k5zk61t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ry8414hqox57k5zk61t.png" alt=" " width="800" height="730"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpy8z0eqe0lwhscc99uf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpy8z0eqe0lwhscc99uf.png" alt=" " width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Introducing Rejigs: A Developer-Friendly Regex Builder for .NET</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Mon, 14 Jul 2025 09:25:54 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/introducing-rejigs-a-developer-friendly-regex-builder-for-net-112b</link>
      <guid>https://dev.to/ahmedshahjr/introducing-rejigs-a-developer-friendly-regex-builder-for-net-112b</guid>
      <description>&lt;p&gt;Regex is powerful — but let’s be honest, it’s also painful.&lt;br&gt;
Too cryptic, too easy to break, and let’s not even talk about debugging them. &lt;/p&gt;

&lt;p&gt;That’s why I use Rejigs — a NuGet package that lets you build, chain, and manage regular expressions using readable, fluent syntax.&lt;br&gt;
Easy to use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8lpxs4dnravet7nmsrsj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8lpxs4dnravet7nmsrsj.png" alt=" " width="800" height="496"&gt;&lt;/a&gt;&lt;br&gt;
✨ Key Features:&lt;br&gt;
✅ Fluent interface (.StartOfLine().Then("hello").Maybe("world").EndOfLine())&lt;br&gt;
✅ Easy to read, build, and maintain regex patterns&lt;br&gt;
✅ No more trial-and-error spaghetti strings&lt;/p&gt;

&lt;p&gt;Available on =&amp;gt; nuget.org/packages/Rejigs&lt;/p&gt;

&lt;p&gt;=&amp;gt; Do you still write raw regex in your apps?&lt;br&gt;
=&amp;gt; Would a tool like this simplify your workflow?&lt;/p&gt;

&lt;p&gt;Drop your thoughts, ideas, or brutal regex horror stories in the comments!&lt;br&gt;
Let’s make regex less scary — one pattern at a time.&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #csharp #regex #NuGet #opensource #developerexperience #fluentapi
&lt;/h1&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Add an .editorconfig file to your solution right from the start! 🛠️</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Sun, 20 Apr 2025 08:47:47 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/add-an-editorconfig-file-to-your-solution-right-from-the-start-5lf</link>
      <guid>https://dev.to/ahmedshahjr/add-an-editorconfig-file-to-your-solution-right-from-the-start-5lf</guid>
      <description>&lt;p&gt;Whenever Starting a new project Add an .editorconfig file to your solution right from the start! 🛠️&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;An EditorConfig file ensures every developer on your team follows the same coding conventions—whether they use Visual Studio, VS Code, Rider, or another IDE. It’s like a rulebook for your codebase, eliminating debates over tabs vs. spaces, indentation, naming, or formatting.&lt;/p&gt;

&lt;p&gt;Key Benefits for Your Team:&lt;/p&gt;

&lt;p&gt;=&amp;gt; Consistency First: Enforce coding styles (e.g., indent size, line endings, charset) across all files and contributors.&lt;/p&gt;

&lt;p&gt;=&amp;gt; Fewer Code Review Hassles: Reduce time spent arguing over formatting. Focus on logic and architecture instead!&lt;/p&gt;

&lt;p&gt;=&amp;gt; IDE-Agnostic: Works seamlessly with most editors—no more "But my IDE auto-formatted it!" excuses.&lt;/p&gt;

&lt;p&gt;=&amp;gt; Built-In .NET Core Support: .NET SDKs natively recognize .editorconfig, making it easy to align with compiler warnings or code analysis rules.&lt;/p&gt;

&lt;p&gt;=&amp;gt; Version Control Friendly: Commit the file to your repo, and everyone stays in sync.&lt;/p&gt;

&lt;p&gt;How to Add It in 2 Minutes:&lt;/p&gt;

&lt;p&gt;In Visual Studio: Right-click your project → Add → New Item → Search for “.editorconfig” → Choose the template.&lt;/p&gt;

&lt;p&gt;Manually: Create a .editorconfig file at the solution root and define your rules.&lt;/p&gt;

&lt;h1&gt;
  
  
  DotNetCore #CodingStandards #DeveloperTips #SoftwareEngineering #TechCommunity #CleanCode #DevOps
&lt;/h1&gt;

&lt;p&gt;Let’s build cleaner, more maintainable codebases—one config file at a time! 🚀&lt;/p&gt;

&lt;p&gt;Example Snippet:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00mlho7yrhgbrcavdinw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00mlho7yrhgbrcavdinw.png" alt="Image" width="636" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>ai</category>
    </item>
    <item>
      <title>🚀 Mastering Filters in ASP.NET Core</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Wed, 16 Oct 2024 04:04:06 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/mastering-filters-in-aspnet-core-5d97</link>
      <guid>https://dev.to/ahmedshahjr/mastering-filters-in-aspnet-core-5d97</guid>
      <description>&lt;p&gt;Mastering Filters in ASP.NET Core.&lt;/p&gt;

&lt;p&gt;If you're working with ASP.NET Core, you're likely already familiar with controllers and actions, but have you explored filters yet? Filters in ASP.NET Core are an incredibly powerful feature that allow you to add functionality before or after an action method is executed, making them perfect for cross-cutting concerns like logging, error handling, and authorization. 🔍&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hdg089kkiq31dedu90l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hdg089kkiq31dedu90l.png" alt="Image description" width="148" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Authorization Filters&lt;br&gt;
Purpose: Check if the user is authorized to access a resource.&lt;br&gt;
Example: [Authorize] attribute.&lt;br&gt;
Usage: Can be applied globally, to controllers, or to specific actions.&lt;/p&gt;

&lt;p&gt;Resource Filters&lt;br&gt;
Purpose: Run code before and after the execution of the rest of the pipeline. Often used for caching.&lt;br&gt;
Example: Implementing IResourceFilter.&lt;br&gt;
Usage: Executes after authorization but before model binding.&lt;/p&gt;

&lt;p&gt;Action Filters&lt;br&gt;
Purpose: Run code before and after an action method executes.&lt;br&gt;
Example: [OnActionExecuting] and [OnActionExecuted] attributes.&lt;br&gt;
Usage: Ideal for logging, validation, or modifying the action result.&lt;/p&gt;

&lt;p&gt;Exception Filters&lt;br&gt;
Purpose: Handle exceptions thrown by action methods or other filters.&lt;br&gt;
Example: Implementing IExceptionFilter.&lt;br&gt;
Usage: Great for global exception handling strategies, such as logging or custom error responses.&lt;/p&gt;

&lt;p&gt;Result Filters&lt;br&gt;
Purpose: Run code before and after the execution of action results.&lt;br&gt;
Example: [OnResultExecuting] and [OnResultExecuted] attributes.&lt;br&gt;
Usage: Useful for modifying the response, e.g., adding headers or changing the result.&lt;/p&gt;

&lt;p&gt;Why are filters a game-changer?&lt;/p&gt;

&lt;p&gt;Because they help you keep your code DRY (Don't Repeat Yourself) and maintainable! 🙌&lt;/p&gt;

&lt;p&gt;If you're looking to simplify your ASP.NET Core development, it’s time to explore the power of filters!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>🚀 Secure your .NET Apps with Visual Studio! 🚀</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Sun, 22 Sep 2024 06:30:00 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/secure-your-net-apps-with-visual-studio-2m4n</link>
      <guid>https://dev.to/ahmedshahjr/secure-your-net-apps-with-visual-studio-2m4n</guid>
      <description>&lt;p&gt;As developers, ensuring the security of our applications is paramount. Did you know that Visual Studio has a feature to help you identify vulnerable packages in your projects? &lt;/p&gt;

&lt;p&gt;By using the “Show only vulnerable packages” option in the NuGet Package Manager, you can quickly pinpoint and address any security issues in your dependencies. &lt;/p&gt;

&lt;p&gt;This feature leverages data from the GitHub Advisory Database to alert you about known vulnerabilities, making it easier to keep your projects secure and up-to-date.&lt;/p&gt;

&lt;p&gt;How to Use It:&lt;/p&gt;

&lt;h1&gt;
  
  
  Open your project in Visual Studio.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Navigate to the NuGet Package Manager.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Check the “Show only vulnerable packages” option.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Review the listed packages and update or replace them as needed.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Stay ahead of potential security threats and ensure your software is robust and reliable. Happy coding! 💻✨
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm97woxh7djmi8ormv6zw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm97woxh7djmi8ormv6zw.png" alt="Image description" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  VisualStudio #NuGet #CyberSecurity #DevSecOps #SoftwareDevelopment
&lt;/h1&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>🚀 TrueForAll in C# 🚀</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Tue, 17 Sep 2024 10:18:21 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/trueforall-in-c-4hd6</link>
      <guid>https://dev.to/ahmedshahjr/trueforall-in-c-4hd6</guid>
      <description>&lt;p&gt;We often encounter scenarios where we need to check if all elements in a collection meet a specific condition. &lt;br&gt;
That’s where TrueForAll comes in, offering a cleaner, more efficient way to handle these checks simplicity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9xqqbv28b5wa3uu5i54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9xqqbv28b5wa3uu5i54.png" alt="Image description" width="630" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🚀 Unlock Your Business Potential with Keyed Services Implementation in .NET Core! 🚀</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Wed, 11 Sep 2024 09:31:31 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/unlock-your-business-potential-with-keyed-services-implementation-in-net-core-4p9f</link>
      <guid>https://dev.to/ahmedshahjr/unlock-your-business-potential-with-keyed-services-implementation-in-net-core-4p9f</guid>
      <description>&lt;p&gt;Are you looking to optimize your application architecture and enhance scalability? Keyed Services in .NET Core might be the game-changer you need! 🔑💻&lt;/p&gt;

&lt;p&gt;Keyed Services in .NET Core provide a robust way to manage dependencies and improve the service selection of your application. By leveraging this powerful feature, you can:&lt;/p&gt;

&lt;p&gt;✨ Boost Scalability: Ensure your services can handle growing loads efficiently. &lt;br&gt;
🔧 Enhance Flexibility: Tailor service implementations based on specific needs or contexts. &lt;br&gt;
⚙️ Improve Maintainability: Simplify updates and management of complex service dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the Interface and Classes Where it needs to implemented
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegf65sjntnow2yr7g28f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegf65sjntnow2yr7g28f.png" alt="Interface Defination" width="800" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inject in the Program.cs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3prmuvzy634b4m7tt8gd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3prmuvzy634b4m7tt8gd.png" alt="Program Injection" width="800" height="852"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inject the Service in you specified Controller or Service
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcb8e1p5px5h2fckwndbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcb8e1p5px5h2fckwndbr.png" alt="Main Service" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice in the constructor we are passing the key for the required service we want to use. we can move it to app settings and use it using the IOptions Pattern also.&lt;br&gt;
This approach allows you to manage multiple implementations of a service and choose the appropriate one at runtime based on a key.&lt;/p&gt;

&lt;p&gt;Let Run the Project using Outlook Service and See the Results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1r6wo0gjpyb6hbo18ez6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1r6wo0gjpyb6hbo18ez6.png" alt="Outlook Response" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;we can see the message return from the Outlook Service.&lt;/p&gt;

&lt;p&gt;Let Change the Key to Gmail Service and Hot Reload Our Project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F444vvlrl8ob2ytp5k7aa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F444vvlrl8ob2ytp5k7aa.png" alt="Gmail Response" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the Response changed to Outlook Service.&lt;/p&gt;

&lt;p&gt;This Key can be changed using iOptions pattern. you can see my previous article how to use  it. Link to the atricle&lt;br&gt;
&lt;a href="https://dev.to/ahmedshahjr/introduction-to-ioptions-pattern-in-net-8-58l4"&gt;IOptions Pattern&lt;/a&gt;&lt;br&gt;
Code For Current Article&lt;br&gt;
&lt;a href="https://github.com/ahmedshahjr/Articles/tree/main/KeyedServices" rel="noopener noreferrer"&gt;Keyed Services GIthubLink&lt;/a&gt;&lt;br&gt;
🔍 #DotNetCore #KeyedServices #SoftwareDevelopment #ApplicationArchitecture #Scalability #CrossPlatform #PerformanceOptimization #TechInnovation #Programming #DevCommunity #CodingBestPractices&lt;/p&gt;

&lt;p&gt;Feel free to connect if you want to dive deeper into how Keyed Services can be implemented in your projects or if you need any guidance on .NET Core!&lt;/p&gt;

&lt;p&gt;💬 Drop a comment or DM me to discuss!&lt;/p&gt;

&lt;h1&gt;
  
  
  TechTalk #ProgrammingTips #SoftwareEngineering #DotNetCoreDevelopment #CodeOptimization
&lt;/h1&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🔍 𝗘𝘅𝗽𝗹𝗼𝗿𝗶𝗻𝗴 𝘁𝗵𝗲 𝗕𝗲𝗻𝗲𝗳𝗶𝘁𝘀 𝗼𝗳 𝗘𝗻𝘂𝗺𝗲𝗿𝗮𝘁𝗶𝗼𝗻𝘀 𝘄𝗶𝘁𝗵 𝗘𝘅𝗽𝗹𝗶𝗰𝗶𝘁 𝗩𝗮𝗹𝘂𝗲𝘀 𝗶𝗻 𝗣𝗿𝗼𝗴𝗿𝗮𝗺𝗺𝗶𝗻𝗴</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Sat, 10 Aug 2024 10:54:44 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/-3fk2</link>
      <guid>https://dev.to/ahmedshahjr/-3fk2</guid>
      <description>&lt;p&gt;𝗻𝘂𝗺𝗲𝗿𝗮𝘁𝗶𝗼𝗻𝘀 are a powerful tool in many programming languages, allowing us to assign names to a set of related values. But why should we consider assigning explicit numbers to these values? Here are a few reasons:&lt;/p&gt;

&lt;p&gt;𝗥𝗲𝗮𝗱𝗮𝗯𝗶𝗹𝗶𝘁𝘆 𝗮𝗻𝗱 𝗨𝗻𝗱𝗲𝗿𝘀𝘁𝗮𝗻𝗱𝗶𝗻𝗴&lt;br&gt;
Enums with numbers can improve code readability. When we assign explicit numbers to enums, it becomes easier to understand the significance of each value, especially when these numbers have a specific meaning attached to them&lt;/p&gt;

&lt;p&gt;𝗦𝘁𝗮𝗯𝗶𝗹𝗶𝘁𝘆 𝗔𝗰𝗿𝗼𝘀𝘀 𝗗𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝘁 𝗩𝗲𝗿𝘀𝗶𝗼𝗻𝘀&lt;br&gt;
 If your software undergoes multiple versions and the enum values are stored in a database, using numbers can ensure stability. Even if you add, remove, or reorder enum members, the underlying values in the database remain consistent&lt;/p&gt;

&lt;p&gt;𝗜𝗻𝘁𝗲𝗿𝗼𝗽𝗲𝗿𝗮𝗯𝗶𝗹𝗶𝘁𝘆 𝘄𝗶𝘁𝗵 𝗢𝘁𝗵𝗲𝗿 𝗦𝘆𝘀𝘁𝗲𝗺𝘀&lt;br&gt;
 When working with external systems that rely on specific numeric values, using enums with numbers can simplify the integration process and reduce potential errors&lt;/p&gt;

&lt;p&gt;𝗘𝗮𝘀𝗲 𝗼𝗳 𝗗𝗲𝗯𝘂𝗴𝗴𝗶𝗻𝗴&lt;br&gt;
 During debugging, it's often easier to spot an incorrect number than an incorrect string. This can make the debugging process more efficient&lt;/p&gt;

&lt;p&gt;hashtag#Programming hashtag#CodingBestPractices hashtag#Enums hashtag#CodeReadability hashtag#SoftwareDevelopment hashtag#CodeMaintenance hashtag#CSharp hashtag#DeveloperCommunity&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i70r6wf5wa7gs4pcl1p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i70r6wf5wa7gs4pcl1p.png" alt="Image description" width="716" height="1194"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Improve Your C# Code with Pattern Matching! 🚀</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Sun, 28 Jul 2024 15:41:44 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/improve-your-c-code-with-pattern-matching-5g7c</link>
      <guid>https://dev.to/ahmedshahjr/improve-your-c-code-with-pattern-matching-5g7c</guid>
      <description>&lt;p&gt;🛑 Avoid complex nested if-else statements&lt;br&gt;
✅ Use pattern matching with switch expressions&lt;/p&gt;

&lt;p&gt;Which approach do you prefer? Share your thoughts and let's discuss the benefits of using pattern matching in C#!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiam1bbq60z1i2to67osy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiam1bbq60z1i2to67osy.png" alt="Image description" width="800" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🚫 Stop the Madness!! Use Cancellation Tokens Effectively in .NET Core🚫</title>
      <dc:creator>Ahmed Shah</dc:creator>
      <pubDate>Wed, 24 Jul 2024 03:59:41 +0000</pubDate>
      <link>https://dev.to/ahmedshahjr/stop-the-madness-use-cancellation-tokens-effectively-in-net-core-2mln</link>
      <guid>https://dev.to/ahmedshahjr/stop-the-madness-use-cancellation-tokens-effectively-in-net-core-2mln</guid>
      <description>&lt;p&gt;Ever get that sinking feeling when your .NET Core app gets stuck in a long-running operation, leaving users frustrated and resources wasted? &lt;/p&gt;

&lt;p&gt;As developers, we often encounter long-running tasks in our applications. Whether it's an API call, a file upload, or a complex calculation, these tasks can sometimes hang or take longer than expected. This is where the power of CancellationToken in .NET Core comes in.&lt;/p&gt;

&lt;p&gt;What Are Cancellation Tokens?&lt;/p&gt;

&lt;p&gt;A CancellationToken is a lightweight object in ASP.NET Core that facilitates cooperative cancellation between threads or components. When a CancellationTokenSource is canceled (usually due to user input or a timeout), all consumers of the associated cancellation token are notified.&lt;/p&gt;

&lt;p&gt;Why Use Cancellation Token?&lt;/p&gt;

&lt;p&gt;🔎 Enhanced User Experience&lt;br&gt;
🔎 Resource Management&lt;br&gt;
🔎 Async Operations&lt;br&gt;
🔎 Graceful Termination&lt;/p&gt;

&lt;p&gt;Integrating CancellationToken in your .NET Core applications is a small change that can have a big impact. It enhances performance, improves user experience, and helps in resource management. 🛠️&lt;/p&gt;

&lt;p&gt;When to Use CancellationToken?&lt;/p&gt;

&lt;p&gt;🔹 API Requests=&amp;gt; Cancel ongoing API calls if the user navigates away or the request takes too long.&lt;br&gt;
🔹 Background Services=&amp;gt; Terminate background tasks gracefully during application shutdown or restarts.&lt;br&gt;
🔹 Parallel Tasks=&amp;gt; Manage parallel operations efficiently, especially when one task's result might affect others.&lt;br&gt;
This Example Below is not recommended For Production its just for learning Purposes.&lt;br&gt;
What are your experiences with CancellationToken? Share your thoughts and let's discuss! 💬👇&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1osajyf8okb68eqydbes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1osajyf8okb68eqydbes.png" alt="Image description" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
