Maybe you should explore better Marshall Interop services and the span related improvements.
IDisposable is definitely an alternative when coupled with Roslyn analysis or SonarQube.
As if doing it in C++ doesn't require the same knowledge level, worse actually, as it also requires ISO C++ mastery and a good knowledge of how each compiler being used handle IB and UB.
Also unless static analysis is getting used, RAII can also get thr ownership wrong, specially with use after move errors, or smart pointers incorrectly given as arguments.
I used Spans extensively. They help (mostly by providing efficient bounds checking), but not much. The main problem, as I mentioned initially, is the composability of this sort of code.
I wasn't trying to give some kind of defence of C++ here, just pointing out the dissimilarities to C#. This particular piece of code would have been far easier in C++ and RAII would have been a huge help, but the system as a whole would have been an utter nightmare in C++ (which I know because I've worked on multiple similar systems in C++).
Sure, but I am the opinion it does compose, if one embraces it isn't the same as writing C++ in C#, not trying to downplay your experience on the matter.
For example, here are the Roslyn analysers for a more RAII like experience with IDisposable,
Turn "DISP004-Don't ignore created IDisposable." into a compiler error and you have your region allocated RAII like experience.
And moving a bit the goal posts, for those scenarios where C# fails completly to provide a usefull solution, we can rewrite just that module into C++ (preferably C++/CLI when only Windows matters), and have the best of both languages.
IDisposable is definitely an alternative when coupled with Roslyn analysis or SonarQube.
As if doing it in C++ doesn't require the same knowledge level, worse actually, as it also requires ISO C++ mastery and a good knowledge of how each compiler being used handle IB and UB.
Also unless static analysis is getting used, RAII can also get thr ownership wrong, specially with use after move errors, or smart pointers incorrectly given as arguments.