<?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: itysu tur</title>
    <description>The latest articles on Forem by itysu tur (@dotnetwithai).</description>
    <link>https://forem.com/dotnetwithai</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%2F3948884%2F2c4659c7-2392-4b63-996b-158777dcb6c1.png</url>
      <title>Forem: itysu tur</title>
      <link>https://forem.com/dotnetwithai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dotnetwithai"/>
    <language>en</language>
    <item>
      <title>Claude Code vs. Legacy .NET: I Picked the Helper, Not the Hero</title>
      <dc:creator>itysu tur</dc:creator>
      <pubDate>Tue, 26 May 2026 11:06:02 +0000</pubDate>
      <link>https://forem.com/dotnetwithai/claude-code-vs-legacy-net-i-picked-the-helper-not-the-hero-1pd1</link>
      <guid>https://forem.com/dotnetwithai/claude-code-vs-legacy-net-i-picked-the-helper-not-the-hero-1pd1</guid>
      <description>&lt;h1&gt;
  
  
  Claude Code vs. Legacy .NET: I Picked the Helper, Not the Hero
&lt;/h1&gt;

&lt;p&gt;Last Tuesday, I was staring down a &lt;code&gt;System.InvalidOperationException: 'Sequence contains no elements.' at MyLegacyProject.DataService.GetActiveUsersAsync()&lt;/code&gt; stack trace. It wasn't the AI's fault directly, but it was generated from a prompt I'd given Claude Sonnet 4.6 to "fix" a related issue in a particularly ancient .NET Framework 4.8 service. That's when I realized this wasn't going to be a simple copy-paste job.&lt;/p&gt;

&lt;p&gt;Our team, like many, has a few critical, undocumented services nobody wants to touch. The idea was to see if Claude Code, specifically the Opus 4.7 model, could accelerate our understanding of this spaghetti code, perhaps even generate some initial fixes or tests, reducing the mental load on our &lt;code&gt;ai coding team dotnet&lt;/code&gt; members. Honestly, I didn't expect much from this initially; I figured it would be another glorified search engine. I was wrong, but not in the way I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unraveling Legacy Code with Claude Opus 4.7
&lt;/h2&gt;

&lt;p&gt;My initial goal was to get Claude to explain a particularly dense, 500-line method in an old &lt;code&gt;DataService&lt;/code&gt; class. This method, &lt;code&gt;CalculateComplexBillingAsync&lt;/code&gt;, had a dozen nested &lt;code&gt;if&lt;/code&gt; statements and some truly creative LINQ queries. I copied the entire method, pasted it into the Claude Opus 4.7 web interface, and asked: "Explain this C# method, identify potential issues, and suggest how it could be refactored for readability and testability, targeting .NET 9 and C# 13 features."&lt;/p&gt;

&lt;p&gt;What I got back wasn't just a line-by-line explanation, but a high-level summary of its purpose, a breakdown of its core logic flows, and even a couple of specific edge cases I'd never considered (like a &lt;code&gt;FirstOrDefault()&lt;/code&gt; without a null check, which was the root of my &lt;code&gt;Sequence contains no elements&lt;/code&gt; error last week). It even proposed using &lt;code&gt;record&lt;/code&gt; types for some DTOs and &lt;code&gt;IAsyncEnumerable&lt;/code&gt; for streaming results, which was a nice touch for a .NET 9 target. For me, the &lt;strong&gt;contextual understanding&lt;/strong&gt; Claude provided was a game-changer. It helped me mentally model the legacy code far faster than just stepping through it in Visual Studio 2026.&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;// My prompt (simplified)&lt;/span&gt;
&lt;span class="c1"&gt;// "Explain this C# method, identify potential issues, and suggest refactoring for .NET 9/C# 13."&lt;/span&gt;
&lt;span class="c1"&gt;// (Followed by 500 lines of legacy C# code)&lt;/span&gt;

&lt;span class="c1"&gt;// Claude's (simplified) response snippet:&lt;/span&gt;
&lt;span class="p"&gt;/*&lt;/span&gt;
&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;primarily&lt;/span&gt; &lt;span class="n"&gt;calculates&lt;/span&gt; &lt;span class="n"&gt;billing&lt;/span&gt; &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;various&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;activity&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Potential&lt;/span&gt; &lt;span class="n"&gt;Issue&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;Lack&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="n"&gt;checking&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;If&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;userActivityLogs&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;matching&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;found&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;will&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Refactoring&lt;/span&gt; &lt;span class="n"&gt;Suggestion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;Replace&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Property&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
csharp&lt;br&gt;
var log = userActivityLogs.FirstOrDefault(l =&amp;gt; l.UserId == userId);&lt;br&gt;
if (log != null)&lt;br&gt;
{&lt;br&gt;
    // ... proceed with log.Property&lt;br&gt;
}&lt;br&gt;
else&lt;br&gt;
{&lt;br&gt;
    // Handle case where no log is found, e.g., default value or throw specific exception.&lt;br&gt;
}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Integrating into the AI Coding Team DotNet Workflow (and the Handoff)
&lt;/h2&gt;

&lt;p&gt;The real challenge wasn't getting Claude to generate code or explanations, but integrating it effectively into our existing &lt;code&gt;ai coding team dotnet&lt;/code&gt; workflow. My colleagues, mostly Rider 2026 users, were initially skeptical. "Another Copilot?" was the common refrain. My personal workflow evolved: I'd use Claude for the initial understanding or boilerplate generation, then bring that into my IDE for refinement.&lt;/p&gt;

&lt;p&gt;One specific "gotcha" I hit repeatedly was Claude's tendency to generate C# 13 preview features or .NET 10 preview APIs when I wasn't explicit enough about our stable .NET 9 target. It took me an embarrassing amount of time to realize the generated code often wouldn't compile without slight modifications or specific &lt;code&gt;using&lt;/code&gt; directives, even when I thought I'd given it enough context. This meant that &lt;code&gt;claude code review&lt;/code&gt; wasn't about blindly accepting its output; it was about treating Claude's suggestions as a very smart junior developer's first draft. Human &lt;strong&gt;oversight remained critical&lt;/strong&gt;. We started treating Claude's output like any other code submitted by a new team member – it needed thorough review, especially for correctness and adherence to our coding standards.&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;// Claude generated this (hypothetically, for .NET 10 preview)&lt;/span&gt;
&lt;span class="c1"&gt;// Example of a small issue I'd often fix manually&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;FeatureToggle&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// .NET 10 preview feature (hypothetically)&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsEnabled&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;featureName&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;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetExperimentalFeature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;featureName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// My manual fix for .NET 9:&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;FeatureToggle&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="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsEnabled&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;featureName&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;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"FEATURE_&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;featureName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToUpperInvariant&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="s"&gt;"enabled"&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;After a month, I'm still figuring out the best way to leverage Claude Code. It's fantastic for understanding complex codebases and generating initial drafts or unit tests, especially when dealing with legacy systems. However, it's not a set-it-and-forget-it solution. The handoff between AI generation and human refinement is where the real work happens, and it requires careful attention to detail, especially regarding target framework and language versions.&lt;/p&gt;




&lt;p&gt;If you've managed to integrate AI code generation tools into your team's .NET code review process without major headaches, I'd love to hear what broke for you and how you fixed it.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>AI's Promise vs. My Reality: The .NET Dev Stack I Actually Use</title>
      <dc:creator>itysu tur</dc:creator>
      <pubDate>Mon, 25 May 2026 08:32:21 +0000</pubDate>
      <link>https://forem.com/dotnetwithai/ais-promise-vs-my-reality-the-net-dev-stack-i-actually-use-5eho</link>
      <guid>https://forem.com/dotnetwithai/ais-promise-vs-my-reality-the-net-dev-stack-i-actually-use-5eho</guid>
      <description>&lt;h1&gt;
  
  
  AI's Promise vs. My Reality: The .NET Dev Stack I Actually Use
&lt;/h1&gt;

&lt;p&gt;I'd heard the buzz about AI coding assistants replacing developers, and honestly, for a while, I bought into the hype. But what I’ve found after months of trying to integrate every shiny new AI into my .NET 9 projects is that the real game-changer isn't replacement, but intelligent augmentation. My personal journey has been less about delegating entire features to an LLM and more about finding that sweet spot where a few specific tools amplify my existing skills, especially when wrestling with legacy C# 13 codebases.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Copilot I Never Expected
&lt;/h2&gt;

&lt;p&gt;My initial foray into the world of &lt;code&gt;dotnet ai tools&lt;/code&gt; started, like many, with GitHub Copilot. Honestly, I expected it to be a novelty, good for trivial boilerplate or maybe filling out a &lt;code&gt;switch&lt;/code&gt; statement. What I ended up finding was that its real strength, for me, lies in its ability to act as a &lt;strong&gt;hyper-aware rubber duck&lt;/strong&gt;. When I'm in Visual Studio 2026 or Rider 2026 and get stuck on a method signature or a common pattern, Copilot often has the right suggestion before I even finish typing.&lt;/p&gt;

&lt;p&gt;Where it truly shines for me is in generating unit tests or simple CRUD operations, especially when there's an existing codebase to learn from. However, I learned the hard way that over-reliance can introduce subtle bugs, particularly with complex &lt;code&gt;async/await&lt;/code&gt; patterns or intricate LINQ queries in C# 13. My rule now is: if it's more than a few lines, I treat Copilot's suggestion as a draft, not gospel.&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;// In a .NET 9 Web API controller, Copilot often nails the boilerplate&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"products"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ActionResult&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;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateProduct&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Product&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="c1"&gt;// Copilot frequently suggests this entire block based on existing repository patterns&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;ModelState&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelState&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;_productRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAsync&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;CreatedAtAction&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="n"&gt;GetProductById&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&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;product&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;product&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;
  
  
  Claude and Cursor: My Pair-Programming Power-Up
&lt;/h2&gt;

&lt;p&gt;For deeper architectural questions, complex refactoring, or simply understanding a gnarly piece of legacy code, my &lt;code&gt;developer ai stack&lt;/code&gt; leans heavily on Claude Opus 4.7, accessed primarily through Cursor 0.42+. I'm still figuring out the optimal way to prompt, but what I've found is that Claude excels at explaining &lt;em&gt;why&lt;/em&gt; a particular piece of code might be problematic or suggesting more robust patterns.&lt;/p&gt;

&lt;p&gt;One specific scenario where this combination saved me an embarrassing amount of time was debugging a tricky &lt;code&gt;ConcurrentDictionary&lt;/code&gt; race condition. I'd tried to implement an &lt;code&gt;async&lt;/code&gt; cache &lt;code&gt;GetOrAdd&lt;/code&gt; pattern myself, only to hit subtle deadlocks. Feeding the problematic C# 13 snippet to Claude via Cursor, leveraging its Model Context Protocol (MCP) awareness, yielded a robust solution. It took a few iterations, but the detailed explanation of &lt;code&gt;Lazy&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; was a game-changer.&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;// Prompt to Claude Opus 4.7 via Cursor 0.42+&lt;/span&gt;
&lt;span class="n"&gt;Explain&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;potential&lt;/span&gt; &lt;span class="n"&gt;pitfalls&lt;/span&gt; &lt;span class="k"&gt;and&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;safety&lt;/span&gt; &lt;span class="n"&gt;concerns&lt;/span&gt; &lt;span class="n"&gt;of&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;NET&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;snippet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;particularly&lt;/span&gt; &lt;span class="n"&gt;related&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;concurrent&lt;/span&gt; &lt;span class="n"&gt;modification&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;_cache&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Suggest&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;safer&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
csharp&lt;br&gt;
public class MyService&lt;br&gt;
{&lt;br&gt;
    private readonly ConcurrentDictionary _cache = new();&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;T&amp;gt; GetOrAddAsync&amp;lt;T&amp;gt;(string key, Func&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; factory)
{
    if (_cache.TryGetValue(key, out var cachedValue))
    {
        return (T)cachedValue;
    }

    var newValue = await factory(); // Potential for multiple threads to execute factory
    _cache.TryAdd(key, newValue);
    return newValue;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
csharp&lt;br&gt;
// Claude Opus 4.7 Response (abbreviated for brevity)&lt;br&gt;
You've correctly identified a race condition. The primary issue with your proposed &lt;code&gt;GetOrAddAsync&lt;/code&gt; is that &lt;code&gt;ConcurrentDictionary.GetOrAdd&lt;/code&gt; expects a synchronous factory function. Directly passing an &lt;code&gt;async&lt;/code&gt; lambda won't properly cache the &lt;em&gt;result&lt;/em&gt; of the &lt;code&gt;Task&lt;/code&gt;, only the &lt;code&gt;Task&lt;/code&gt; object itself, leading to potential re-execution or incomplete caching.&lt;/p&gt;

&lt;p&gt;To properly handle asynchronous factory functions and ensure single execution of the factory across multiple threads, I typically lean on a pattern involving &lt;code&gt;Lazy&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; or an &lt;code&gt;AsyncLazy&amp;lt;T&amp;gt;&lt;/code&gt; implementation. This ensures the asynchronous operation is performed once and its result is safely cached.&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;MyService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Store Lazy&amp;lt;Task&amp;lt;object&amp;gt;&amp;gt; to ensure the async factory runs only once&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;ConcurrentDictionary&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;,&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&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;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_cache&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetOrAddAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&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;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;factory&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;lazyTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetOrAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Lazy&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&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;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;async&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="c1"&gt;// The factory is executed inside the Lazy, ensuring single execution&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="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;LazyThreadSafetyMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExecutionAndPublication&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Critical for thread safety&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&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;lazyTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Await the result of the Lazy&amp;lt;Task&amp;lt;object&amp;gt;&amp;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;
  
  
  Visual Studio + Copilot Edits: The IDE's New Brain
&lt;/h2&gt;

&lt;p&gt;The biggest shift in my daily coding rhythm has been the tight integration of AI directly into my IDE. Visual Studio 2026, with its latest Copilot Edits and Copilot for Workspaces features, has become an indispensable part of my &lt;code&gt;best ai for csharp&lt;/code&gt; toolkit. It's not just auto-completion anymore; it's proactive refactoring and code generation right where I need it.&lt;/p&gt;

&lt;p&gt;For quick, localized transformations, Copilot Edits is fantastic. I can highlight a &lt;code&gt;for&lt;/code&gt; loop and prompt it to "Refactor this to use LINQ," and it usually gets it right on the first try. It handles mundane tasks like extracting methods, renaming variables consistently, or even adding XML documentation comments based on context. I'm still figuring out how to make Copilot for Workspaces truly effective for larger, multi-file refactors across our sprawling monorepo, but for focused, in-file changes, it's a significant time-saver.&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;// Scenario: Using Copilot Edits in VS 2026&lt;/span&gt;
&lt;span class="c1"&gt;// Original code selected by me:&lt;/span&gt;
&lt;span class="c1"&gt;// var activeUsers = new List&amp;lt;User&amp;gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// foreach (var user in allUsers)&lt;/span&gt;
&lt;span class="c1"&gt;// {&lt;/span&gt;
&lt;span class="c1"&gt;//     if (user.IsActive &amp;amp;&amp;amp; user.LastLogin &amp;gt; DateTime.UtcNow.AddDays(-30))&lt;/span&gt;
&lt;span class="c1"&gt;//     {&lt;/span&gt;
&lt;span class="c1"&gt;//         activeUsers.Add(user);&lt;/span&gt;
&lt;span class="c1"&gt;//     }&lt;/span&gt;
&lt;span class="c1"&gt;// }&lt;/span&gt;
&lt;span class="c1"&gt;// return activeUsers.OrderBy(u =&amp;gt; u.Username).ToList();&lt;/span&gt;

&lt;span class="c1"&gt;// My prompt to Copilot Edits: "Refactor this to use LINQ for filtering and ordering."&lt;/span&gt;

&lt;span class="c1"&gt;// Copilot Edits output:&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;allUsers&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;user&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&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;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LastLogin&lt;/span&gt; &lt;span class="p"&gt;&amp;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="nf"&gt;AddDays&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OrderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Username&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;p&gt;So, where am I now? My current developer AI stack isn't about replacing me, but about making me a faster, more informed .NET developer. I'm still figuring out how to leverage Copilot for Workspaces effectively for cross-project context, especially with our monorepo setup. It feels like we're just scratching the surface of what's possible.&lt;/p&gt;




&lt;p&gt;If you've managed to integrate &lt;code&gt;dotnet ai tools&lt;/code&gt; into your daily workflow for complex refactoring or legacy codebase understanding, I'd genuinely love to hear about your specific wins and especially your failures. What broke for you, and how did you fix it?&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My Two Weeks with Claude Sonnet 4.6 for C# Development</title>
      <dc:creator>itysu tur</dc:creator>
      <pubDate>Sun, 24 May 2026 11:07:39 +0000</pubDate>
      <link>https://forem.com/dotnetwithai/my-two-weeks-with-claude-sonnet-46-for-c-development-1l21</link>
      <guid>https://forem.com/dotnetwithai/my-two-weeks-with-claude-sonnet-46-for-c-development-1l21</guid>
      <description>&lt;h1&gt;
  
  
  My Two Weeks with Claude Sonnet 4.6 for C# Development
&lt;/h1&gt;

&lt;p&gt;Last month, I spent two weeks trying to integrate Claude Sonnet 4.6 into my daily C# workflow, specifically targeting a gnarly .NET 6 Web API codebase that's slowly being migrated to .NET 9. I wasn't looking for a magic bullet, just some pragmatic help.&lt;/p&gt;

&lt;p&gt;Our team's been dabbling with AI tools for a while, mostly Copilot and some GPT-4o for documentation. My personal goal was to see if Claude Sonnet 4.6 could genuinely assist with refactoring and debugging existing C# 10 code, or if it was just another glorified autocomplete. I was looking for a fresh perspective, especially on some tricky LINQ queries and async deadlocks that had been haunting us in Visual Studio 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  What surprised me about its C# understanding
&lt;/h2&gt;

&lt;p&gt;Honestly, I expected Sonnet 4.6 to struggle with the nuances of C# 10 and our specific domain, but it often surprised me with its contextual understanding. My initial attempts involved pasting small, isolated functions, which worked okay. The real game-changer came when I started feeding it entire &lt;code&gt;.cs&lt;/code&gt; files, or even pairs of related files (like a service and its interface). It felt like the Model Context Protocol (MCP) was really helping it build a richer internal model.&lt;/p&gt;

&lt;p&gt;For example, I had a complex LINQ query in a repository method that was a performance bottleneck. I pasted the entire &lt;code&gt;ProductRepository.cs&lt;/code&gt; file into Claude with a simple prompt. It didn't just suggest a basic &lt;code&gt;Where&lt;/code&gt; clause; it understood the intent and proposed an &lt;code&gt;AsQueryable()&lt;/code&gt; followed by multiple &lt;code&gt;Where&lt;/code&gt; and &lt;code&gt;Select&lt;/code&gt; statements, even suggesting an &lt;code&gt;Include&lt;/code&gt; for a related entity that wasn't immediately obvious from the method signature alone. It still took me a few tries to get the exact &lt;code&gt;Select&lt;/code&gt; projection right.&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;// Prompt to Claude Sonnet 4.6&lt;/span&gt;
&lt;span class="p"&gt;/*&lt;/span&gt;
&lt;span class="n"&gt;Given&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;following&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;ProductRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;refactor&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;GetFilteredProductsAsync&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;performant&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;especially&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;filtering&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt; &lt;span class="n"&gt;optional&lt;/span&gt; &lt;span class="n"&gt;criteria&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Consider&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nn"&gt;IQueryable&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;building&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="n"&gt;dynamically&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
csharp&lt;br&gt;
// ProductRepository.cs&lt;br&gt;
public class ProductRepository : IProductRepository&lt;br&gt;
{&lt;br&gt;
    private readonly AppDbContext _context;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public ProductRepository(AppDbContext context) =&amp;gt; _context = context;

public async Task&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt; GetFilteredProductsAsync(
    string? nameFilter, int? categoryId, decimal? minPrice)
{
    var products = await _context.Products
        .Where(p =&amp;gt;
            (string.IsNullOrEmpty(nameFilter) || p.Name.Contains(nameFilter)) &amp;amp;&amp;amp;
            (!categoryId.HasValue || p.CategoryId == categoryId.Value) &amp;amp;&amp;amp;
            (!minPrice.HasValue || p.Price &amp;gt;= minPrice.Value))
        .ToListAsync();
    return products;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*/

// Claude Sonnet 4.6 Response (excerpt):
/*
Okay, here's a refactored version of `GetFilteredProductsAsync` using `IQueryable` to build the query dynamically, which can be more efficient as the filtering happens at the database level before materialization.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
csharp&lt;br&gt;
public async Task&amp;gt; GetFilteredProductsAsync(&lt;br&gt;
    string? nameFilter, int? categoryId, decimal? minPrice)&lt;br&gt;
{&lt;br&gt;
    IQueryable query = _context.Products;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!string.IsNullOrEmpty(nameFilter))
{
    query = query.Where(p =&amp;gt; p.Name.Contains(nameFilter));
}

if (categoryId.HasValue)
{
    query = query.Where(p =&amp;gt; p.CategoryId == categoryId.Value);
}

if (minPrice.HasValue)
{
    query = query.Where(p =&amp;gt; p.Price &amp;gt;= minPrice.Value);
}

// Example of including related data, if needed, for better context awareness
// query = query.Include(p =&amp;gt; p.Category);

return await query.ToListAsync();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
plaintext&lt;br&gt;
This dynamic query building was a definite improvement. The &lt;strong&gt;contextual understanding&lt;/strong&gt; of the existing code was surprisingly robust.&lt;/p&gt;
&lt;h2&gt;
  
  
  Where it broke and how I learned to prompt better
&lt;/h2&gt;

&lt;p&gt;While its understanding was good, Claude Sonnet 4.6 isn't a mind reader. I screwed up several times by not providing enough explicit detail. For instance, I was debugging a &lt;code&gt;System.Text.Json&lt;/code&gt; serialization issue, and Claude initially suggested &lt;code&gt;Newtonsoft.Json&lt;/code&gt; attributes or configuration. It took me an embarrassing amount of time to realize I needed to explicitly state our project used &lt;code&gt;System.Text.Json&lt;/code&gt; exclusively.&lt;/p&gt;

&lt;p&gt;This taught me a critical lesson: even with advanced models like Claude Sonnet 4.6, you still need to be precise. For C# 13 and .NET 9 work, I started adding specific directives to my prompts, like "Using C# 13 and .NET 9, please refactor this..." or "Given this &lt;code&gt;Foo.cs&lt;/code&gt; and &lt;code&gt;BarService.cs&lt;/code&gt; from our ASP.NET Core 9 project...". This significantly improved the relevance and accuracy of its suggestions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// My improved prompting style:
"Given the following C# 13 code from `OrderProcessor.cs` and `OrderRepository.cs` in our .NET 9 project, refactor `ProcessOrderAsync` to use a more robust error handling strategy with `IResult` from ASP.NET Core 9, instead of throwing exceptions directly. Assume `OrderRepository.GetByIdAsync` can return null. Also, ensure all database operations are wrapped in a transaction using `_context.Database.BeginTransactionAsync()`."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This level of detail made a huge difference. Without it, I found myself getting generic C# 8 or .NET 6 suggestions that required more manual tweaking than the initial problem warranted. &lt;strong&gt;Specificity is key&lt;/strong&gt;, even for advanced models.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup I settled on (for now)
&lt;/h2&gt;

&lt;p&gt;For this personal review, I mostly stuck with the official Claude web interface for Sonnet 4.6, pasting code directly into the chat. I did experiment briefly with a custom VS Code extension that leverages the Claude Opus 4.7 API for larger, multi-file refactors, but for the focused task of evaluating Sonnet 4.6, the web UI was sufficient. My reasoning was simple: minimize integration complexity to isolate the model's performance.&lt;/p&gt;

&lt;p&gt;I found myself using Sonnet 4.6 for quick code reviews, suggesting minor refactors, or generating boilerplate for new interfaces based on existing classes. For anything involving significant architectural changes or complex interactions across many files, I still leaned on my own architectural understanding and, if available, the more powerful Claude Opus 4.7. It's not a replacement for Rider 2026 or Visual Studio 2026's deep refactoring tools, but it's a solid complement.&lt;/p&gt;

&lt;p&gt;My workflow often looked like this: identify a problematic C# file, paste it into Sonnet 4.6 with a clear prompt, review the suggestions, and then manually apply and refine them in my IDE. I might be wrong about this, but I think this "human-in-the-loop" approach is currently the most effective way to leverage models like Claude Sonnet 4.6 for C# development.&lt;/p&gt;




&lt;p&gt;So, after two weeks, Claude Sonnet 4.6 earned a spot in my toolkit, mostly for its ability to quickly parse context and suggest alternative approaches. I'm still figuring out the best way to leverage it for complex, multi-file refactors without turning into a prompt engineer, but it's a solid contender for C# code help. Your mileage may vary, of course.&lt;/p&gt;




&lt;p&gt;If you've spent time with Claude Sonnet 4.6 or another model on a particularly tricky C# 13 codebase, I'd genuinely love to hear about your wins and frustrations in the comments.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>ai</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>My Two-Week Sprint: Claude Sonnet 4.6 and C# Productivity</title>
      <dc:creator>itysu tur</dc:creator>
      <pubDate>Sun, 24 May 2026 11:07:33 +0000</pubDate>
      <link>https://forem.com/dotnetwithai/my-two-week-sprint-claude-sonnet-46-and-c-productivity-3kfe</link>
      <guid>https://forem.com/dotnetwithai/my-two-week-sprint-claude-sonnet-46-and-c-productivity-3kfe</guid>
      <description>&lt;h1&gt;
  
  
  My Two-Week Sprint: Claude Sonnet 4.6 and C# Productivity
&lt;/h1&gt;

&lt;p&gt;Last month, I almost gave up on really integrating AI into my daily C# development workflow. Every attempt felt like more overhead than help, until I tried a focused two-week experiment with Claude Sonnet 4.6.&lt;/p&gt;

&lt;p&gt;Like many of us, I've dabbled with AI coding assistants – mostly Copilot for boilerplate, maybe a quick Stack Overflow search with ChatGPT. But the promise of a true &lt;code&gt;claude code productivity&lt;/code&gt; boost always felt just out of reach. My goal was simple: track my actual time spent coding on a specific feature, first without, then with, Claude Sonnet 4.6 as my primary AI assistant for C# 13 and .NET 9 projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Initial Hump and the 'Aha!' Moment
&lt;/h2&gt;

&lt;p&gt;Honestly, I was skeptical at first. My first few days with Claude Sonnet 4.6 felt like a clumsy dance. I'd paste a chunk of C# code, ask for a refactor, and get back something that was technically correct but missed the nuance of our domain-driven design. I learned the hard way that just dumping code isn't enough; Claude, like any junior dev, needs proper &lt;strong&gt;context window&lt;/strong&gt; and clear intent.&lt;/p&gt;

&lt;p&gt;The 'aha!' moment came when I started feeding it architectural constraints, specific patterns we use, and even links to our internal wiki documentation via the Model Context Protocol (MCP) in Visual Studio 2026. Last Tuesday, I was refactoring an old &lt;code&gt;IQueryable&lt;/code&gt; extension method for a new .NET 9 API, and it was taking forever. I gave Claude the existing method, our &lt;code&gt;PaginationRequest&lt;/code&gt; DTO, and a description of the desired new filtering logic. What I got back wasn't just working code, but code that felt like it belonged in our codebase.&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;// My initial prompt (simplified in blog, but I provided full method and DTOs):&lt;/span&gt;
&lt;span class="c1"&gt;// "I need to update this IQueryable extension to support dynamic filtering based on a list of FilterCriteria.&lt;/span&gt;
&lt;span class="c1"&gt;// Each criteria has a PropertyName, Operator (e.g., "eq", "gt"), and Value.&lt;/span&gt;
&lt;span class="c1"&gt;// The existing method only handles basic pagination and sorting.&lt;/span&gt;
&lt;span class="c1"&gt;// Use System.Linq.Dynamic.Core for dynamic expression building."&lt;/span&gt;

&lt;span class="c1"&gt;// Claude's suggested addition (excerpt, after several refinements):&lt;/span&gt;
&lt;span class="c1"&gt;// It understood the need for dynamic LINQ and handled various operators.&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;IQueryable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ApplyFiltering&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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="n"&gt;IQueryable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&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;FilterCriteria&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;filters&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;config&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;ParsingConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;AllowNewToEvaluateExpressions&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;// From System.Linq.Dynamic.Core&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;filter&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;filters&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;propertyType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;GetProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BindingFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IgnoreCase&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BindingFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Public&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BindingFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&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;propertyType&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&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;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ChangeType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;propertyType&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;dynamicLinqQuery&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Operator&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="k"&gt;switch&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"eq"&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; == @0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"gt"&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &amp;gt; @0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"lt"&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &amp;lt; @0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"contains"&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.Contains(@0)"&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;$"Unsupported operator: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Operator&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;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&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;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dynamicLinqQuery&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="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Simplified FilterCriteria DTO (provided in prompt context)&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;FilterCriteria&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;PropertyName&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;string&lt;/span&gt; &lt;span class="n"&gt;Operator&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="c1"&gt;// e.g., "eq", "gt", "contains"&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;Value&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Numbers: Where I Saw Real Gains
&lt;/h2&gt;

&lt;p&gt;I tracked my time using a simple stopwatch app on my phone. For a specific set of new features and &lt;strong&gt;refactoring tasks&lt;/strong&gt; on an existing microservice, I spent 5 days working without heavy AI assistance (only standard Copilot completions) and 5 days with Claude Sonnet 4.6 as my primary assistant in Rider 2026. The results were genuinely surprising. My average task completion time dropped by about 35% during the Claude-assisted week. This wasn't 10x for everything, but for the right kinds of tasks, it felt like it.&lt;/p&gt;

&lt;p&gt;Where did I see the biggest gains? Not in writing greenfield code from scratch, surprisingly. That still requires deep architectural thought from me. The real &lt;code&gt;ai csharp workflow&lt;/code&gt; accelerator was in understanding existing, unfamiliar codebases and generating robust unit tests. When I had to dive into a service written by a former colleague, Claude Sonnet 4.6 was invaluable for explaining complex LINQ queries or obscure async patterns, then helping me quickly scaffold tests for them. I might be wrong about this, but it felt like its larger context window (compared to what I typically use with Copilot) made it much better at digesting an entire file or even a small project.&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;// My prompt to Claude (simplified, but I provided the full method):&lt;/span&gt;
&lt;span class="c1"&gt;// "Explain what this method does and suggest a unit test scenario for its edge cases.&lt;/span&gt;
&lt;span class="c1"&gt;// Consider the 'status' enum and potential null/empty inputs."&lt;/span&gt;

&lt;span class="c1"&gt;// Example method for context (from my codebase)&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="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ProcessOrderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderRequest&lt;/span&gt; &lt;span class="n"&gt;request&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;request&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&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="nf"&gt;IsNullOrWhiteSpace&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;CustomerId&lt;/span&gt;&lt;span class="p"&gt;))&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;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order request."&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;customer&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;_customerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetByIdAsync&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;CustomerId&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;customer&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&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;CustomerNotFoundException&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;CustomerId&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;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&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="n"&gt;request&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="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pending&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="n"&gt;OrderDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_dateTimeProvider&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="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_orderRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAsync&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="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_unitOfWork&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CommitAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;_eventPublisher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Publish&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;OrderCreatedEvent&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="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;));&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="c1"&gt;// Claude's suggested test (excerpt):&lt;/span&gt;
&lt;span class="c1"&gt;// It identified the null/empty checks and the customer not found scenario effectively.&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&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;ProcessOrderAsync_ShouldThrowArgumentException_WhenRequestIsNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
    &lt;span class="n"&gt;OrderRequest&lt;/span&gt; &lt;span class="n"&gt;nullRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&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;OrderService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Mocks omitted for brevity&lt;/span&gt;

    &lt;span class="c1"&gt;// Act &amp;amp; Assert&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThrowsAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;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;ProcessOrderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nullRequest&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="n"&gt;Fact&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;ProcessOrderAsync_ShouldThrowCustomerNotFoundException_WhenCustomerDoesNotExist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;request&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;OrderRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"nonExistent"&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="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="n"&gt;OrderItemRequest&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;mockCustomerRepo&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;Mock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ICustomerRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;mockCustomerRepo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Setup&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;=&amp;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;GetByIdAsync&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;CustomerId&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;ReturnsAsync&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="k"&gt;null&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;OrderService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockCustomerRepo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Act &amp;amp; Assert&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThrowsAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CustomerNotFoundException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;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;ProcessOrderAsync&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  My Current Setup and What's Still Fuzzy
&lt;/h2&gt;

&lt;p&gt;What I ended up with for my &lt;code&gt;developer productivity ai&lt;/code&gt; setup involves Claude Sonnet 4.6 (sometimes Opus 4.7 for really thorny problems) via the Cursor 0.42+ IDE extension, which supports the Model Context Protocol. This allows me to selectively feed entire files, or even directories, into the prompt without a ton of copy-pasting. For quick, localized completions, Copilot is still fantastic, but for anything requiring broader context or complex transformations, Claude became my go-to.&lt;/p&gt;

&lt;p&gt;One thing I'm still figuring out is the optimal way to manage long-running conversations. It's easy to get lost in a massive chat history, and sometimes the AI starts 'hallucinating' based on old, irrelevant context. Your mileage may vary, but for me, starting fresh or explicitly clearing context for a new task often yields better results. I'm also not sure if this scales to truly massive enterprise codebases without hitting context limits or just becoming too slow. The &lt;strong&gt;integration&lt;/strong&gt; is good, but not perfect yet.&lt;/p&gt;

&lt;p&gt;So, while I didn't literally 10x &lt;em&gt;every&lt;/em&gt; aspect of my C# productivity, I found a significant, measurable uplift in specific, often time-consuming tasks. My &lt;code&gt;ai csharp workflow&lt;/code&gt; is definitely evolving, and I'm spending less time wrestling with existing code and more on design. It feels like having a really smart, well-read rubber duck.&lt;/p&gt;




&lt;p&gt;If you've integrated Claude Sonnet 4.6 or Opus 4.7 into your C# 13 development, especially for legacy refactoring, I'd love to hear about your concrete wins or the specific challenges you ran into.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
