SafeHandle types must have public constructor
Historically, passing SafeHandle-derived types to P/Invokes and COM methods has implicitly required a parameterless constructor of any visibility when a SafeHandle
-derived type is passed as a ref
or out
parameter or a return type. Source-generated interop in .NET 7 allowed this behavior to enable easier migration from DllImportAttribute-based P/Invokes. At the same time, we updated the SafeHandle documentation to tell implementers to provide a public
parameterless constructor in their derived type. This breaking change makes that recommendation a requirement for source-generated marshalling.
Previous behavior
A SafeHandle-derived type was required to have a parameterless constructor of any visibility when it was used:
- As a
ref
orout
parameter or a return type in a LibraryImportAttribute-attributed method. - In a method on a GeneratedComInterfaceAttribute-attributed interface.
New behavior
A SafeHandle-derived type is required to have a public
parameterless constructor when it's used:
- As a
ref
orout
parameter or a return type in a LibraryImportAttribute-attributed method. - In a method on a GeneratedComInterfaceAttribute-attributed interface.
If the type doesn't have a public
parameterless constructor, the interop source generator emits a compile error.
Version introduced
.NET 8 Preview 5
Type of breaking change
This change can affect source compatibility.
Reason for change
The interop source generators are changing to push more code out of the source generators themselves and into the core .NET libraries. As part of this change, the interop team is starting to enforce the recommended guidelines for more maintainable and understandable interop code.
Recommended action
Change the existing non-public
parameterless constructor on the SafeHandle
-derived type to be public
.