diff --git a/OpenRA.Game/Exts.cs b/OpenRA.Game/Exts.cs index f9cca3b774..06a9f70a38 100644 --- a/OpenRA.Game/Exts.cs +++ b/OpenRA.Game/Exts.cs @@ -109,13 +109,23 @@ namespace OpenRA public static V GetOrAdd(this Dictionary d, K k, V v) { +#if NET5_0_OR_GREATER + // SAFETY: Dictionary cannot be modified whilst the ref is alive. + ref var value = ref System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(d, k, out var exists); + if (!exists) + value = v; + return value; +#else if (!d.TryGetValue(k, out var ret)) d.Add(k, ret = v); return ret; +#endif } public static V GetOrAdd(this Dictionary d, K k, Func createFn) { + // Cannot use CollectionsMarshal.GetValueRefOrAddDefault here, + // the creation function could mutate the dictionary which would invalidate the ref. if (!d.TryGetValue(k, out var ret)) d.Add(k, ret = createFn(k)); return ret;