diff --git a/src/WinRT.Runtime/ComWrappersSupport.net5.cs b/src/WinRT.Runtime/ComWrappersSupport.net5.cs index 003782ec7..9e23bf3c4 100644 --- a/src/WinRT.Runtime/ComWrappersSupport.net5.cs +++ b/src/WinRT.Runtime/ComWrappersSupport.net5.cs @@ -71,7 +71,12 @@ internal static unsafe InspectableInfo GetInspectableInfo(IntPtr pThis) return InspectableInfoTable.GetValue(_this.GetType(), o => PregenerateNativeTypeInformation(o).inspectableInfo); } - public static T CreateRcwForComObject(IntPtr ptr) + public static T CreateRcwForComObject(IntPtr ptr) + { + return CreateRcwForComObject(ptr, true); + } + + private static T CreateRcwForComObject(IntPtr ptr, bool tryUseCache) { if (ptr == IntPtr.Zero) { @@ -83,7 +88,9 @@ public static T CreateRcwForComObject(IntPtr ptr) // ComWrappers API surface, so we are achieving it via a thread local. We unset it after in case // there is other calls to it via other means. CreateRCWType.Value = typeof(T); - var rcw = ComWrappers.GetOrCreateObjectForComInstance(ptr, CreateObjectFlags.TrackerObject); + + var flags = tryUseCache ? CreateObjectFlags.TrackerObject : CreateObjectFlags.TrackerObject | CreateObjectFlags.UniqueInstance; + var rcw = ComWrappers.GetOrCreateObjectForComInstance(ptr, flags); CreateRCWType.Value = null; // Because .NET will de-duplicate strings and WinRT doesn't, // our RCW factory returns a wrapper of our string instance. @@ -99,12 +106,15 @@ public static T CreateRcwForComObject(IntPtr ptr) winrtObj.Resurrect(); } - return rcw switch - { - ABI.System.Nullable ns => (T)(object) ns.Value, - ABI.System.Nullable nt => (T)(object) nt.Value, - _ => (T) rcw - }; + return rcw switch + { + ABI.System.Nullable ns => (T)(object)ns.Value, + ABI.System.Nullable nt => (T)(object)nt.Value, + T castRcw => castRcw, + _ when tryUseCache => CreateRcwForComObject(ptr, false), + _ => throw new ArgumentException(string.Format("Unable to create a wrapper object. The WinRT object {0} has type {1} which cannot be assigned to type {2}", ptr, rcw.GetType(), typeof(T))) + }; + } public static bool TryUnwrapObject(object o, out IObjectReference objRef)