title: Unit test for PINVOKE memory management
body: <p>I have a C# application (.net core 3.1) which uses some unmanaged C++ code. The interop is implemented using PINVOKE.</p>
  <p>My code does something like this (simplified):</p>
  <pre><code>double[] managedArray = new[] { 1.0, 2.0, 3.0 };
  
  // This is the first PINVOKE call
  // The unmanaged object is expected to copy the array internally.
  UnmanagedObject unmanaged = CreateUnmanagedObject(managedArray);
  
  [...]
  
  // This is another PINVOKE call which uses the data passed in to the constructor.
  // This call can also happen in a different method.
  // At this point managedArray could already have been garbage collected.
  unmanaged.DoStuff();
  </code></pre>
  <p>I'm following the pattern, that the C++ code should copy the array internally before storing it in the UnmanagedObject state.</p>
  <p>Now I'd like to write a unit test for the proposition <em>The unmanaged object is expected to copy the array internally.</em>
  My attempt looks like this:</p>
  <pre><code>UnmanagedObject unmanaged;
  {
      double[] managedArray = new[] { 1.0, 2.0, 3.0 };
      unmanaged = CreateUnmanagedObject(managedArray);
  }
  // With this call I'm relying on the fact, that the GC will collect
  // managedArray, because it's gone out of scope.
  System.GC.Collect();
  
  // If DoStuff works properly here, it means that the C++ code
  // has copied the array internally.
  unmanaged.DoStuff();
  </code></pre>
  <p>Is the phrase <em>the GC will collect <code>managedArray</code>, because it's gone out of scope</em> correct? Is that guaranteed to always happen?</p>
  <p>[I edited the question to make it more clear by removing some irrelevant stuff. Some of the comments do not apply anymore.]</p>