Microsoft is Redefining ‘Unsafe’ in C# to Bridge the Gap Between Managed Memory and Rust-like Rigor

Table of Contents
A New Era of Memory Visibility
For decades, C# has maintained a delicate balance: providing the productivity of a garbage-collected, managed language while allowing developers a “trap door” into the raw memory management of C. That trap door is the unsafe keyword. While the vast majority of enterprise developers never touch it, unsafe is critical for high-performance scenarios, operating system interop, and direct hardware manipulation. However, that flexibility comes with a lack of visibility—once a piece of code is marked unsafe, the danger is often buried deep within a call stack.
Microsoft is now moving to change that. .NET product manager Richard Lander recently detailed a significant architectural shift in how C# handles memory safety, aiming to make the language more aligned with the rigorous safety enforcement seen in Rust, without abandoning the automatic memory management that defines the .NET ecosystem.
The Propagation Problem
Under the current model, marking a method as unsafe allows the use of pointers and direct memory addresses. However, the unsafe modifier is largely localized. If a safe method calls an unsafe method, the safety boundary is crossed silently; the caller doesn’t necessarily have to acknowledge that it is interacting with potentially volatile, unmanaged memory.
Starting with C# 16—slated for a late 2027 release alongside .NET 12 (an LTS release)—Microsoft will introduce a propagation model. In this new system, marking a method as unsafe will automatically designate it as requires-unsafe. This means the “danger” signal travels up the chain: any method calling that unsafe function must itself be in an unsafe context. Overrides of safe base members will also be prohibited from being unsafe unless the base member was already marked as such.
Essentially, Microsoft is turning the unsafe keyword into a warning label that cannot be easily ignored by the rest of the application. This doesn’t make the code itself “safer” in terms of preventing crashes, but it makes the risk far more transparent during code reviews and security audits.
Decoupling Pointers from Danger
One of the most nuanced changes in the proposal is the reclassification of pointer types. In previous versions of C#, the mere presence of a pointer often triggered the need for an unsafe block. The new model seeks to distinguish between holding a pointer and using it.
In the upcoming revisions, simply declaring pointer types or using certain pointer expressions will no longer be considered unsafe. The restriction will instead trigger at the moment of dereferencing—the actual act of accessing unmanaged memory. This shift allows developers to structure their data more efficiently without polluting every surrounding method with safety warnings, reserving the unsafe label for the actual point of risk.
The Path to Adoption
Microsoft is cognizant that a breaking change to the language’s core safety model could alienate developers. Consequently, the changes will be opt-in for C# 16. Developers can continue using the legacy C# 1.0 model if desired, though the .NET runtime libraries themselves will opt-in to the new standards.
To drive adoption, Microsoft is considering a system of “safety badges” for packages on NuGet. These badges would signal to developers whether a library has adopted the new safety model, effectively creating a market incentive for maintainers to modernize their code. Lander has indicated that while the move is currently opt-in, the long-term goal is to make this model the default for the entire ecosystem.
Why This Matters for the “Boring” App
For the average developer building a web API or a business application, these changes will be invisible. They will never write a pointer, and they will never see a requires-unsafe error. However, the systemic impact is profound. By forcing low-level library authors to be explicit about memory boundaries, Microsoft is reducing the surface area for memory-corruption vulnerabilities in the underlying frameworks that power millions of applications.
The industry-wide push toward memory-safe languages, spurred by mandates from agencies like the CISA and the White House, has put a spotlight on languages like C and C++. By adopting a “managed Rust” philosophy, C# is positioning itself as a viable middle ground: a language that offers the safety of a managed runtime with the explicit, auditable memory control required for high-performance systems programming.