Rust vs C#: Which One Would I Actually Use?
I’ve been a C# developer for a long time.
Rust came much later.
And after spending time working with both languages, I’ve realized something:
I really like Rust.
I also really like C#.
Yeah, I know. That’s not nearly as exciting as declaring one language the winner and starting a war in the comments.
But the more I’ve used both, the more I’ve realized that I don’t necessarily see Rust and C# as competitors. They’re tools that I would reach for in very different situations.
So instead of trying to answer “Which language is better?”, I think the more useful question is:
When would I actually choose Rust over C#, and when would I choose C# over Rust?
C# Is My Comfort Zone
I’ve been working with C# professionally for years, so obviously there’s some bias here.
If you gave me an idea for an application and told me to get something working quickly, there’s a very good chance I’m reaching for C#.
The combination of C#, .NET, NuGet, and the tooling around the language makes it incredibly easy to just get shit done.
Need an API?
ASP.NET Core.
Need a desktop application?
You’ve got options.
Need to connect to a database?
Entity Framework makes it almost stupidly easy.
Need authentication, dependency injection, logging, configuration, JSON serialization, or about 500 other things?
There’s probably already something built into .NET or available through NuGet.
And modern C# is just a really pleasant language to write.
public record Player(string Name, int Score);
var players = new List<Player>
{
new("Kevin", 100),
new("Park Goat", 9001)
};
var winner = players
.OrderByDescending(x => x.Score)
.First();
Console.WriteLine($"{winner.Name} wins!");
It’s readable.
Even if you don’t use C# every day, you can probably figure out what’s happening there.
That’s something I really appreciate about the language.
Then There’s Rust
Rust is… different.
My first experience learning Rust involved a lot more:
“Why the hell won’t you let me do this?”
followed several hours later by:
“Oh. That’s actually a really good reason.”
Rust forces you to think about things that C# usually handles for you.
Memory ownership.
Borrowing.
Lifetimes.
Mutability.
Thread safety.
And, of course, the borrow checker.
Everyone who learns Rust eventually becomes acquainted with the borrow checker.
At first, it feels like you’re fighting the compiler.
Eventually you start realizing the compiler is preventing you from doing some really stupid shit.
Garbage Collection Changes Everything
One of the biggest differences between the two languages is memory management.
C# uses garbage collection.
You create objects, use them, and eventually the .NET garbage collector cleans up memory that isn’t being used anymore.
That’s an enormous convenience.
Rust doesn’t have a garbage collector.
Instead, Rust uses its ownership and borrowing system to determine when memory can be cleaned up.
For example:
fn main() {
let name = String::from("Park Goat");
print_name(&name);
println!("{name} survived!");
}
fn print_name(name: &String) {
println!("{name}");
}
We’re borrowing name rather than transferring ownership of it.
Once you understand what Rust is doing, it starts making a lot of sense.
Getting to the point where you understand it?
Well…
That’s part of the Rust experience.
Rust Makes Me Think More
This is simultaneously one of my favorite and least favorite things about Rust.
Rust makes me think more about how I’m designing something.
That’s great when I’m building software where performance, memory usage, concurrency, or reliability really matter.
It’s less great when I just want to throw together an internal tool on a Friday afternoon.
Sometimes I don’t want to think about lifetimes.
Sometimes I want to query a database, turn the result into JSON, send it to Angular, and go home.
That’s where C# shines.
Where I’d Choose C#
If someone came to me today and wanted me to build a typical business application, there’s a very good chance I’d choose C#.
Things like:
- REST APIs
- Business applications
- Internal tools
- Database-heavy applications
- SaaS backends
- Enterprise software
- Rapid prototypes
C# and .NET are just incredibly productive for this kind of work.
Could you build all of that in Rust?
Absolutely.
But could and should aren’t always the same thing.
If C# lets me build something in considerably less time and Rust doesn’t provide a meaningful advantage for that particular application, I’m probably using C#.
Where I’d Choose Rust
Rust becomes much more interesting to me when I’m getting closer to the system itself.
If I’m building something where performance and resource usage matter significantly, Rust starts looking really attractive.
Things like:
- High-performance services
- System utilities
- Networking software
- Embedded applications
- Performance-sensitive microservices
- CLI tools
- Software where predictable memory usage matters
I’ve used Rust for services where its characteristics actually provided a benefit, and that’s where I think the language really starts to make sense.
It’s fast.
It doesn’t require a garbage collector.
You can build extremely small and efficient applications.
And Rust’s compiler catches an almost annoying number of mistakes before your program ever runs.
I say almost annoying because it’s incredibly frustrating when you’re learning.
Then six months later you’re thankful it yelled at you.
But What About Performance?
This is where Rust usually gets the big win in internet comparisons.
And yes, Rust can be ridiculously fast.
But modern .NET is also really damn fast.
For the overwhelming majority of business applications I’ve worked on, C# performance isn’t remotely the bottleneck.
Your database query taking 800ms doesn’t suddenly become fast because you rewrote your API in Rust.
Bad architecture written in Rust is still bad architecture.
A poorly designed database is still a poorly designed database.
Choosing a faster programming language doesn’t magically fix everything around it.
There are absolutely workloads where Rust’s performance characteristics matter.
I just don’t think “Rust is faster” is enough justification by itself to rewrite every C# application on Earth.
Rust’s Learning Curve Is Real
If you already know C#, Java, or another garbage-collected language, moving to Rust can be humbling.
You’ll write something that looks completely reasonable.
Rust will disagree.
You’ll change it.
Rust will disagree differently.
You’ll Google the error.
You’ll find a Stack Overflow answer from someone who appears to have a PhD in lifetimes.
You’ll question your career choices.
Then you’ll finally get it compiling.
And strangely…
it feels fantastic.
Rust has probably made me think about memory and software architecture more than almost any other language I’ve learned.
Even when I’m writing C#, some of those lessons carry over.
So Which One Do I Prefer?
If you forced me to choose only one language to use for everything?
C#.
But that’s largely because of the kind of software I build.
It’s productive, mature, extremely capable, and I’ve spent years working with it.
But if you asked me which language I find more interesting?
That might actually be Rust.
Rust scratches a completely different programming itch.
There’s something satisfying about building a tiny compiled executable, knowing exactly how memory is being handled, and having the compiler aggressively checking your work.
So my personal rule is pretty simple:
I use C# when developer productivity is the priority.
I use Rust when the characteristics of Rust actually solve a problem I have.
I don’t rewrite something in Rust just because Rust is cool.
And I don’t automatically use C# just because it’s comfortable.
Pick the tool that makes sense for the problem.
Although if you’re learning Rust for the first time and currently screaming at the borrow checker…
Don’t worry.
That’s apparently part of the installation process.
Bonus:
If you are looking at game dev, try C# with Unity – simple way to get going….