DEV Community

itysu tur
itysu tur

Posted on

3 Unexpected Ways Copilot Edges CodeWhisperer for .NET 9 Devs

3 Unexpected Ways Copilot Edges CodeWhisperer for .NET 9 Devs

I processed over 2,000 lines of legacy C# last month, untangling years of technical debt in a crucial microservice. It was a grind, and honestly, the thought of doing it without some AI assistance felt like going back to the stone age. My team’s been using GitHub Copilot for Workspaces for a while, and it’s become indispensable for our .NET 9 projects. But with all the buzz around Amazon CodeWhisperer's recent C# model updates and its deep integration into AWS services, I started to wonder if we were missing out. For a couple of weeks, I decided to run both in parallel in Visual Studio 2026 and Rider 2026, specifically looking at their ai code completion csharp capabilities.

My Initial Jitters and Basic Completion

Setting up both was straightforward enough. Copilot for Workspaces was already active, and CodeWhisperer's plugin for Visual Studio 2026 (or Rider 2026) installed without a hitch. My first impression, especially when writing new methods or simple classes, was that Copilot felt more organic. It would often suggest completions that extended naturally from my variable names or comments. CodeWhisperer, on the other hand, sometimes felt a little too eager to complete an entire method or class with boilerplate that wasn't quite what I needed, often requiring more backspacing than actual coding.

For example, when I was creating a simple DTO, Copilot would usually give me property names that made sense in the context of the surrounding code. CodeWhisperer, especially in a fresh file, would sometimes just dump a generic public class MyClass { public int Id { get; set; } ... } which was rarely useful. I found myself hitting Esc more often with CodeWhisperer. It took me an embarrassing amount of time to realize I needed to be much more explicit with my initial code or comments for CodeWhisperer to grasp the intent.

// Scenario: Creating a new DTO for a user profile update request
// Copilot often suggests relevant properties based on common patterns.
public class UserProfileUpdateRequest
{
    public Guid UserId { get; set; }
    public string FirstName { get; set; } // Copilot often suggests LastName, Email right after
    public string LastName { get; set; }
    public string Email { get; set; }
    // ...
}

// CodeWhisperer, without much context, might be more generic or verbose initially.
// It often felt like I had to type more of the structure before it "understood".
// Example of a prompt I'd type, then CodeWhisperer might try to complete:
// public class UserProfileUpdateRequest
// {
//     public string Username { get; set; }
//     public string Password { get; set; } // Less relevant for a *profile update*
//     // ...
// }
Enter fullscreen mode Exit fullscreen mode

Where Contextual Understanding Made the Difference

This is where the copilot vs codewhisperer debate really started to resolve for me. I spend a lot of time in existing, often sprawling, C# applications. Copilot for Workspaces, especially with its expanded context window, felt like it had a much better grasp of the surrounding files and the overall project structure. When I was refactoring a particularly gnarly service class, Copilot would offer suggestions that actually adhered to the existing naming conventions and patterns within that specific codebase, even if they were a bit idiosyncratic.

Last Tuesday, I was debugging a 500-line method (yes, really) that handled complex business logic. My goal was to extract a few helper methods. Copilot consistently suggested method signatures and implementations that fit the existing data flow and object types. CodeWhisperer, powered by its latest C# model, often proposed entirely new approaches or introduced types that weren't present, forcing me to re-type or discard its suggestions. It felt like CodeWhisperer was trying to give me "best practice" code rather than "this project's practice" code. Honestly, I expected CodeWhisperer to be better at this, given Amazon's scale, but for legacy code, it just wasn't as effective for me.

// Original problematic code snippet (simplified for brevity)
public async Task<Result> ProcessOrderAsync(OrderRequest request)
{
    // ... many lines of validation and data fetching ...

    if (request.IsSpecialOrder)
    {
        // Complex logic for special orders, ~100 lines
        // Copilot would suggest: "Extract SpecialOrderValidation(request)"
        // CodeWhisperer often suggested: "Create new SpecialOrderProcessor.Process(request)"
        // which wasn't quite what I was going for.
    }
    else
    {
        // Regular order processing
    }

    // ... more logic ...
}

// Copilot's helpful suggestion for extraction within the existing class:
// (User types 'private bool IsValidSpecialOrder(OrderRequest request)' and Copilot fills)
private bool IsValidSpecialOrder(OrderRequest request)
{
    // Check specific conditions for special orders
    // ...
    return true;
}
Enter fullscreen mode Exit fullscreen mode

The Ecosystem Play and My Final Setup

Beyond raw code completion, the ecosystem integration was a significant factor. As a heavy GitHub user, Copilot for Workspaces integrates seamlessly with my pull requests, code reviews, and even suggests changes based on my team's coding standards pulled from our repositories. I'm still figuring out how to fully leverage Copilot Edits for multi-file changes, but the potential is huge. CodeWhisperer, naturally, shines when you're deeply embedded in the AWS ecosystem. If I were building a new serverless application on AWS Lambda with .NET 9, I could see CodeWhisperer's direct integration with AWS SDKs and services being a massive time-saver. It automatically suggests code for connecting to S3, DynamoDB, and other services, which is incredibly powerful if that's your stack.

For my current work, which involves a mix of legacy on-prem and modern Azure-hosted microservices, Copilot’s broader contextual understanding and integration with GitHub felt more aligned. Your mileage may vary, especially if AWS is your primary cloud provider. What I ended up doing was keeping Copilot for Workspaces as my primary ai code completion csharp tool, mainly because its suggestions required less correction in my daily workflow. I still have CodeWhisperer installed, but I disable it by default and only enable it when I'm specifically working on a new AWS-centric project where I know its specialized knowledge will be an advantage.

# How I toggle CodeWhisperer in Visual Studio 2026 (simplified representation)
# In reality, this is done via Extensions -> Manage Extensions, or a specific CodeWhisperer menu.
# This shell command is illustrative of the intent.
# My preference is to have Copilot active by default.

# Example: Disable CodeWhisperer globally for general .NET development
# (simulated via CLI, actual UI interaction in VS/Rider)
# aws codewhisperer disable-extension --profile my-dev-profile

# Example: Enable CodeWhisperer when starting a new AWS-specific project
# aws codewhisperer enable-extension --profile my-dev-profile
Enter fullscreen mode Exit fullscreen mode

I'm currently running Copilot for Workspaces alongside C# 13 in Visual Studio 2026. While CodeWhisperer has certainly improved, for now, Copilot provides a smoother, more context-aware experience across the diverse C# projects I juggle. I’m still figuring out how to best integrate AI tools for high-level architectural suggestions rather than just code completion.


If you've run both GitHub Copilot and Amazon CodeWhisperer on complex legacy C# codebases, I'd love to hear what specific challenges or triumphs you encountered.

Top comments (0)