Microsoft is Redefining ‘Unsafe’ in C# to Close the Memory Safety Gap

Table of Contents
A Shift in Memory Philosophy
For over two decades, C# has balanced the convenience of automatic memory management with a ‘trap door’ for developers who need raw performance: the unsafe keyword. This modifier allows developers to bypass the .NET garbage collector and use pointers, effectively writing C-style code within a managed environment. While essential for low-level tasks like interacting with hardware or operating system kernels, it has long been a source of potential instability and security vulnerabilities.
Microsoft is now planning a fundamental shift in how this boundary is managed. According to .NET product manager Richard Lander, the company intends to move C# toward a model where memory-safety enforcement is more rigorous and transparent. The goal isn’t to eliminate unsafe code—which remains a technical necessity for high-performance systems—but to ensure that when unsafe code is used, it is explicitly visible and carefully contained.
The ‘Requires-Unsafe’ Propagation
The most significant change, slated for C# 16, involves how the unsafe designation behaves. Currently, the unsafe modifier is relatively passive; it allows a method to use pointers, but it doesn’t necessarily force the calling code to acknowledge the risk.
Under the new proposal, marking a method as unsafe will also categorize it as requires-unsafe. This creates a propagation effect: any method calling an unsafe function must itself be in an unsafe context. This design mimics the way languages like Rust handle unsafe blocks, ensuring that the “risk” of memory corruption doesn’t leak silently into safe parts of the application. If a base member is safe, overrides cannot be unsafe, preventing a scenario where a safe interface is suddenly implemented by a dangerous, pointer-heavy subclass.
Furthermore, the scope of the unsafe modifier is being narrowed. Microsoft will remove the ability to mark an entire type (class or struct) as unsafe. Instead, the designation will move down to the individual methods, properties, and fields where the danger actually resides. In a move to reduce unnecessary noise, simply using a pointer type will no longer be considered unsafe; only the act of dereferencing that pointer—actually touching unmanaged memory—will trigger the requirement for an unsafe context.
Implementation and the NuGet Ecosystem
Given the potential for breaking changes, Microsoft is taking a staggered approach to the rollout. The new model is expected to appear in preview with C# 15 and .NET 11, before becoming an opt-in feature in C# 16 (anticipated for late 2027 alongside the .NET 12 LTS release).
To drive adoption, Microsoft is considering a social and technical nudge via NuGet, the primary package repository for .NET developers. The company is exploring the addition of “safety badges” on packages, signaling to developers whether a library has opted into the new safety model. This transparency would allow architects to make informed decisions about the risk profile of their dependencies.
The Rust Influence
The industry trend toward memory-safe languages is well-documented, with the White House and CISA recently urging developers to move away from memory-unsafe languages like C and C++. While C# has always been safer than C, the “leakage” of unsafe pointer logic has been a lingering critique.
By making unsafe code more visible and easier to audit through static code analyzers and required safety documentation, Microsoft is essentially trying to provide “managed Rust.” The objective is to maintain the developer productivity of a garbage-collected language while adopting the rigorous safety boundaries that make Rust a favorite for systems programming.
While the average business application developer—who likely never touches a pointer—won’t feel these changes, the impact on the .NET runtime libraries and high-performance middleware will be substantial. As Lander noted, this is a high-leverage change designed to increase confidence in the overall safety of the C# ecosystem.