Problem: Manual Refactoring Takes Hours
You need to modernize a legacy C# codebase—converting old patterns to records, nullable reference types, or async/await—but doing it manually across dozens of files would take days.
You'll learn:
- How to enable and configure IntelliCode Agent in VS 2026
- Using AI-powered bulk refactoring across entire projects
- Reviewing and applying suggested transformations safely
Time: 12 min | Level: Intermediate
Why This Happens
Legacy C# codebases accumulate outdated patterns as the language evolves. Manual refactoring is error-prone and time-consuming, especially when changes affect multiple files or require understanding complex dependencies.
Common symptoms:
- Hundreds of warnings about nullable reference types
- Old-style property declarations instead of primary constructors
- Missing async/await patterns causing thread blocking
- Inconsistent naming conventions across the codebase
Solution
Step 1: Enable IntelliCode Agent
# Verify VS 2026 version (requires 17.12+)
& "C:\Program Files\Microsoft Visual Studio\2026\Professional\Common7\IDE\devenv.exe" /version
Expected: Version 17.12.0 or higher
Open Visual Studio 2026 → Tools → Options → IntelliCode → Enable "IntelliCode Agent (Preview)"
If it fails:
- Option not visible: Update VS 2026 to latest version via Visual Studio Installer
- Grayed out: Ensure you have Professional or Enterprise edition (not Community)
Step 2: Analyze Your Project
Right-click your project in Solution Explorer → IntelliCode → "Analyze for Refactoring Opportunities"
// IntelliCode will scan for patterns like this old code
public class Customer
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
Why this works: The agent uses trained models on millions of C# repos to identify modernization opportunities based on C# 12 best practices.
Wait 30-60 seconds for analysis to complete. The IntelliCode Agent pane opens showing suggestions categorized by impact.
Step 3: Review Suggested Refactorings
The agent shows suggestions in priority order:
High Impact (apply first):
- Convert properties to auto-properties or primary constructors
- Add nullable reference type annotations
- Replace
Task.Resultwithawait
Medium Impact:
- Use pattern matching instead of type checks
- Convert to record types where appropriate
- Simplify LINQ queries
Low Impact:
- Naming convention fixes
- Expression-bodied members
varkeyword usage
// Example suggestion preview
// Before:
public class Customer
{
private string _name;
public string Name { get { return _name; } set { _name = value; } }
}
// After (IntelliCode Agent suggestion):
public class Customer
{
public required string Name { get; init; }
}
Select suggestions carefully: Check the "Impact Analysis" column showing how many files will change.
Step 4: Apply Refactorings
For each suggestion:
- Click the suggestion to see Preview Changes
- Review the diff for all affected files
- Uncheck any files where the change doesn't make sense
- Click Apply
// IntelliCode handles complex cases automatically
// Before:
if (obj is Customer)
{
Customer customer = (Customer)obj;
Console.WriteLine(customer.Name);
}
// After (pattern matching suggestion):
if (obj is Customer customer)
{
Console.WriteLine(customer.Name);
}
Best practice: Apply one category at a time (all "High Impact" first), then rebuild and test before moving to the next category.
Step 5: Bulk Apply Across Solution
For safe transformations (like auto-property conversion):
- Select multiple suggestions using Ctrl+Click
- Click "Apply Selected to Entire Solution"
- IntelliCode shows a consolidated diff view
- Click Apply All
Why this is safe: The agent runs Roslyn analyzers to ensure changes don't break compilation. It skips files where the transformation might cause issues.
Verification
# Rebuild solution
dotnet build
# Run existing tests to catch behavioral changes
dotnet test
You should see:
- Build succeeds with zero errors
- Reduced warning count (check Output → Build)
- All existing tests pass
If tests fail:
- Use Git diff to review what changed
- IntelliCode marks "High Confidence" vs "Needs Review" changes
- Undo questionable changes: Right-click in IntelliCode Agent pane → Revert
Step 6: Enable Continuous Suggestions
Tools → Options → IntelliCode → Agent Settings
Enable:
- ☑ "Show inline suggestions while typing" - Real-time refactoring hints
- ☑ "Auto-apply safe refactorings on save" - Auto-properties, using statements
- ☐ "Apply breaking changes automatically" - Leave OFF for safety
Why: Inline suggestions help you write modern C# as you code. Auto-apply only affects non-breaking changes like formatting.
Advanced: Custom Refactoring Patterns
Create team-specific refactoring rules:
Tools → IntelliCode → Custom Patterns
<!-- Example: Enforce company logging pattern -->
<Pattern>
<Match>
<Code>Console.WriteLine(*)</Code>
</Match>
<Replace>
<Code>_logger.LogInformation(*)</Code>
</Replace>
<Scope>Project</Scope>
</Pattern>
Save as .vsrefactor file in your solution root. IntelliCode Agent will now suggest this transformation.
Verification
Final checklist:
# Check code quality metrics
dotnet build /p:RunCodeAnalysis=true
# Ensure no new nullable warnings
dotnet build /p:TreatWarningsAsErrors=true
You should see:
- Modernized code using C# 12 features
- Reduced cyclomatic complexity (IntelliCode shows metrics)
- Consistent patterns across the codebase
What You Learned
- IntelliCode Agent analyzes entire projects for refactoring opportunities
- Bulk transformations save hours compared to manual refactoring
- Preview and rollback features make it safe for production code
Limitations:
- Requires VS 2026 Professional/Enterprise (not available in VS Code yet)
- Some suggestions need manual review (check "Confidence" score)
- Works best with C# 10+ codebases (limited support for .NET Framework 4.x)
When NOT to use:
- Mission-critical code without comprehensive tests
- During active development sprints (conflicts with uncommitted changes)
- Projects with extensive reflection (agent can't analyze dynamic code paths)
Common Scenarios
Scenario 1: Migrate to Records
Problem: You have DTOs that should be immutable records.
// IntelliCode detects this pattern
public class ProductDto
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
IntelliCode suggestion: Convert to record
// After applying suggestion
public record ProductDto(int Id, string Name, decimal Price);
Impact: 47 files changed, 0 test failures
Scenario 2: Async/Await Conversion
Problem: Blocking calls causing performance issues.
// IntelliCode flags this as blocking
public string GetData()
{
return _httpClient.GetStringAsync(url).Result; // Blocks thread
}
IntelliCode suggestion: Convert to async pattern
// After applying suggestion
public async Task<string> GetDataAsync()
{
return await _httpClient.GetStringAsync(url); // Non-blocking
}
Note: IntelliCode automatically updates all callers to await GetDataAsync().
Scenario 3: Nullable Reference Types
Problem: 200+ warnings after enabling nullable reference types.
// IntelliCode analyzes null flow
public void ProcessCustomer(Customer customer)
{
Console.WriteLine(customer.Name.ToUpper()); // Warning CS8602
}
IntelliCode suggestions:
- Add null check:
if (customer?.Name != null) - Make parameter nullable:
Customer? customer - Add null-forgiving operator:
customer.Name!.ToUpper()
Best choice: IntelliCode ranks option 1 as "High Confidence" based on codebase patterns.
Troubleshooting
Agent Shows No Suggestions
Cause: Project not using C# 10+ or Roslyn analyzers disabled
Fix:
<!-- Add to .csproj -->
<PropertyGroup>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
</PropertyGroup>
Restart analysis after saving.
"This refactoring cannot be applied"
Cause: Code has compilation errors or uses reflection
Fix:
- Resolve all build errors first:
dotnet build - For reflection-heavy code, apply suggestions manually
- Check Output → IntelliCode Agent for specific blockers
Performance: Analysis Takes 5+ Minutes
Cause: Large solution with 100+ projects
Fix:
- Analyze one project at a time: Right-click specific project
- Exclude test projects: Tools → Options → IntelliCode → Exclusions
- Increase analysis timeout: Options → IntelliCode → Advanced → Timeout = 300s
Tested on Visual Studio 2026 v17.12.1, .NET 8 & 9, Windows 11