Most “getting more out of Copilot” advice starts with a feature tour — chat, inline suggestions, agents, the CLI, slash commands — and assumes you’ll figure out where each one fits. I’ve found that backwards. The features only make sense once you anchor them to the work you’re actually doing.
So instead of learning the tool, start with a task from your own backlog. Then ask one question: do I need to think through this, or do I need it done and verified? That single distinction maps cleanly onto the two ways I use Copilot — chat and agentic workflows — and it’s the whole game.
Start with the task, not the mode
Chat is for understanding, comparing, planning, drafting, and explaining. It keeps you in the loop on every step. You read, you push back, you refine.
Agentic workflows are for multi-step, bounded tasks where you want a deliverable at the end — code changed, tests passing, a diff to review. You set the boundaries up front, then check the result like you’d check a teammate’s pull request.
Neither is “better.” They solve different problems. Once you stop reaching for whichever one is open and start picking based on the task, Copilot gets noticeably more useful.
Where chat earns its keep in .NET work
Five situations where I open chat before writing a line of code.
1. Understanding a legacy service
Before touching anything, I want the lay of the land. Something like:
| |
It surfaces the business logic and coupling I’d otherwise rediscover the hard way.
2. Generating test coverage
Good unit tests are mostly about remembering the edge cases. Chat is good at enumerating them:
| |
3. Planning a refactor before committing to it
I’d rather argue about the shape of a change in prose than in a half-finished branch:
| |
4. Cross-file configuration changes
This is where VS Code’s chat shines, because the change spans file types:
| |
5. Diagnosing a build failure
The Copilot CLI fits this naturally because you’re already in the terminal:
| |
What a good prompt actually contains
The difference between “Improve this code” and a prompt that works is structure. A strong prompt carries four things:
- Goal — what you want accomplished
- Code or output — the context from your project
- Constraints — what must stay the same
- Expected shape — the format you want back
Put together, it reads like this:
| |
That out-performs a vague request every time, because you’ve removed the guesswork about what “improve” means to you.
Agentic flows worth delegating
When the task is well-scoped and verifiable, I hand the whole thing over.
1. Fill test gaps
Add the missing unit tests for a specific feature flow, with the success criterion being that the tests pass.
2. Repetitive pattern refactoring
Standardise logging, nullable warnings, or exception handling across projects while preserving behaviour.
3. A CLI fix loop
Investigate a failure, implement a fix, rerun the tests, and summarise the changes — all inside the terminal.
4. Multi-file changes via the cloud agent
Propagate a correlation ID across middleware, logging, and integration tests, with the boundaries spelled out.
5. Cross-stack configuration
Update .NET config binding, Bicep templates, GitHub Actions workflows, and docs together, keeping naming consistent.
The common thread: each one has a clear edge and a way to tell whether it worked.
Choosing where to run it
| Surface | Best for |
|---|---|
| Visual Studio | Deep solution work — understanding services and existing test patterns |
| VS Code | Cross-file changes that span code and configuration |
| Copilot CLI | Terminal workflows — build failures, debugging loops |
| Cloud coding agent | Bounded, delegatable tasks that run in the background and return a diff |
Habits that make Copilot pull its weight
A few of these compound more than any feature does:
- Set clear boundaries on the task.
- Name your constraints explicitly — and say what must not change.
- Ask for a useful output format.
- Review the result like a peer code review, not a lottery ticket.
For .NET work specifically, the constraints I name most often are: keep public APIs unchanged, follow the existing xUnit patterns, preserve the dependency injection registration style, update nullable annotations only in named projects, and rerun targeted tests rather than the whole suite.
Final thought
The value here isn’t generating individual lines of code — autocomplete already did that. It’s reasoning through real engineering work and delegating well-scoped tasks so you can stay on the parts that need judgement.
So don’t treat Copilot as something to study. Pull one real task off your backlog, decide whether it needs thinking or doing, and let the tool meet you there.
Adapted from Wendy Breiding’s Doing More with GitHub Copilot as a .NET Developer on the .NET Blog.
