Repository: dotnet/runtime
File: src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs (C#)

Code before:
            {
                exception->Value = ex;
            }
        }

        internal static void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome)
        {
            // COMPAT: We never pass null to MarshalManagedToNative.
            if (pManagedHome is null)
            {
                *pNativeHome = IntPtr.Zero;
                return;
            }

            *pNativeHome = marshaler.MarshalManagedToNative(pManagedHome);
        }

        [UnmanagedCallersOnly]
        internal static void ConvertContentsToManaged(ObjectHandleOnStack* marshaler, ObjectHandleOnStack* pManagedHome, IntPtr* pNativeHome, ObjectHandleOnStack* exception)
        {
            try
            {
                ICustomMarshaler customMarshaler = (ICustomMarshaler)marshaler->Value;
                object? managedHome = pManagedHome->Value;
                ConvertContentsToManaged(customMarshaler, ref managedHome, pNativeHome);
                pManagedHome->Value = managedHome!;
            }
            catch (Exception ex)
            {
                exception->Value = ex;
            }
        }

        internal static void ConvertContentsToManaged(ICustomMarshaler marshaler, ref object? pManagedHome, IntPtr* pNativeHome)
        {
            // COMPAT: We never pass null to MarshalNativeToManaged.
            if (*pNativeHome == IntPtr.Zero)
            {
                pManagedHome = null;
                return;
            }

            pManagedHome = marshaler.MarshalNativeToManaged(*pNativeHome);
        }

        [UnmanagedCallersOnly]
        internal static void ClearNative(ObjectHandleOnStack* marshaler, ObjectHandleOnStack* pManagedHome, IntPtr* pNativeHome, ObjectHandleOnStack* exception)
        {
            try
            {
                ICustomMarshaler customMarshaler = (ICustomMarshaler)marshaler->Value;

Review comment (refactor):
The null-forgiving operator is used when assigning to `pManagedHome->Value`, but `managedHome` can legitimately be null after calling `ConvertContentsToManaged` (either explicitly set on line 882 of the helper method, or potentially returned by `ICustomMarshaler.MarshalNativeToManaged`). The `ObjectHandleOnStack.Value` property setter should accept `object?` instead of `object`, or this line should be changed to handle the null case explicitly without the null-forgiving operator.
```suggestion
                if (managedHome is null)
                {
                    pManagedHome->Value = null;
                }
                else
                {
                    pManagedHome->Value = managedHome;
                }
```

Code after:
            }
        }

        internal static void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome)
        {
            // COMPAT: We never pass null to MarshalManagedToNative.
            if (pManagedHome is null)
            {
                *pNativeHome = IntPtr.Zero;
                return;
            }

            *pNativeHome = marshaler.MarshalManagedToNative(pManagedHome);
        }

        [UnmanagedCallersOnly]
        internal static void ConvertContentsToManaged(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
        {
            try
            {
                ConvertContentsToManaged(*pMarshaler, ref *pManagedHome, pNativeHome);
            }
            catch (Exception ex)
            {
                *pException = ex;
            }
        }

        internal static void ConvertContentsToManaged(ICustomMarshaler marshaler, ref object? pManagedHome, IntPtr* pNativeHome)
        {
            // COMPAT: We never pass null to MarshalNativeToManaged.
            if (*pNativeHome == IntPtr.Zero)
            {
                pManagedHome = null;
                return;
            }

            pManagedHome = marshaler.MarshalNativeToManaged(*pNativeHome);
        }

        [UnmanagedCallersOnly]
        internal static void ClearNative(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
        {
            try
            {
                ClearNative(*pMarshaler, ref *pManagedHome, pNativeHome);
            }
            catch (Exception ex)
            {
                *pException = ex;
            }