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

Code before:

            if (s_switches == null)
            {
                // Compatibility switches are rarely used. Initialize the Dictionary lazily
                Interlocked.CompareExchange(ref s_switches, new Dictionary<string, bool>(), null);
            }

            lock (s_switches)
            {
                s_switches[switchName] = isEnabled;
            }
        }

#if MONO
        internal static unsafe void Setup(char** pNames, uint* pNameLengths, char** pValues, uint* pValueLengths, int count)
        {
            Debug.Assert(s_dataStore == null, "s_dataStore is not expected to be inited before Setup is called");
            s_dataStore = new Dictionary<string, object?>(count);
            for (int i = 0; i < count; i++)
            {
                s_dataStore.Add(new string(pNames[i], 0, (int)pNameLengths[i]), new string(pValues[i], 0, (int)pValueLengths[i]));
            }
        }
#elif !NATIVEAOT
        [UnmanagedCallersOnly]
        internal static unsafe void Setup(char** pNames, char** pValues, int count, Runtime.CompilerServices.ObjectHandleOnStack* pException)
        {
            try
            {
                Debug.Assert(s_dataStore == null, "s_dataStore is not expected to be inited before Setup is called");
                s_dataStore = new Dictionary<string, object?>(count);
                for (int i = 0; i < count; i++)
                {
                    s_dataStore.Add(new string(pNames[i]), new string(pValues[i]));
                }
            }
            catch (Exception ex)
            {
                pException->Value = ex;
            }
        }
#endif
    }
}


Review comment (refactor):
The exception parameter is declared as `nint pException` but should be `ObjectHandleOnStack* exception` for consistency with the other UnmanagedCallersOnly methods in StubHelpers.cs. While `nint` is compatible with pointer types, using the actual pointer type makes the intent clearer and maintains consistency across the codebase.

Code after:
            ArgumentException.ThrowIfNullOrEmpty(switchName);

            if (s_switches == null)
            {
                // Compatibility switches are rarely used. Initialize the Dictionary lazily
                Interlocked.CompareExchange(ref s_switches, new Dictionary<string, bool>(), null);
            }

            lock (s_switches)
            {
                s_switches[switchName] = isEnabled;
            }
        }

#if MONO
        internal static unsafe void Setup(char** pNames, uint* pNameLengths, char** pValues, uint* pValueLengths, int count)
        {
            Debug.Assert(s_dataStore == null, "s_dataStore is not expected to be inited before Setup is called");
            s_dataStore = new Dictionary<string, object?>(count);
            for (int i = 0; i < count; i++)
            {
                s_dataStore.Add(new string(pNames[i], 0, (int)pNameLengths[i]), new string(pValues[i], 0, (int)pValueLengths[i]));
            }
        }
#elif !NATIVEAOT
        [UnmanagedCallersOnly]
        internal static unsafe void Setup(char** pNames, char** pValues, int count, Exception* pException)
        {
            try
            {
                Debug.Assert(s_dataStore == null, "s_dataStore is not expected to be inited before Setup is called");
                s_dataStore = new Dictionary<string, object?>(count);
                for (int i = 0; i < count; i++)
                {
                    s_dataStore.Add(new string(pNames[i]), new string(pValues[i]));
                }
            }
            catch (Exception ex)
            {
                *pException = ex;
            }
        }
#endif
    }
}