diff --git a/src/Benchmarks/Benchmarks.csproj b/src/Benchmarks/Benchmarks.csproj index 246612262..104d78d5e 100644 --- a/src/Benchmarks/Benchmarks.csproj +++ b/src/Benchmarks/Benchmarks.csproj @@ -16,14 +16,15 @@ - + + - - + + diff --git a/src/WinRT.Runtime/AgileReference.cs b/src/WinRT.Runtime/AgileReference.cs index d910470b3..1b5a387cf 100644 --- a/src/WinRT.Runtime/AgileReference.cs +++ b/src/WinRT.Runtime/AgileReference.cs @@ -6,7 +6,7 @@ namespace WinRT { public class AgileReference : IDisposable { - private readonly static Guid CLSID_StdGlobalInterfaceTable = Guid.Parse("00000323-0000-0000-c000-000000000046"); + private readonly static Guid CLSID_StdGlobalInterfaceTable = new(0x00000323, 0, 0, 0xc0, 0, 0, 0, 0, 0, 0, 0x46); private readonly static Lazy Git = new Lazy(() => GetGitTable()); private readonly IAgileReference _agileReference; private readonly IntPtr _cookie; diff --git a/src/WinRT.Runtime/ComWrappersSupport.cs b/src/WinRT.Runtime/ComWrappersSupport.cs index 8efe4077e..118c057ef 100644 --- a/src/WinRT.Runtime/ComWrappersSupport.cs +++ b/src/WinRT.Runtime/ComWrappersSupport.cs @@ -63,49 +63,48 @@ public static IObjectReference GetObjectReferenceForInterface(IntPtr externalCom return null; } - using var unknownRef = ObjectReference.FromAbi(externalComObject); + var unknownRef = ObjectReference.FromAbi(externalComObject); - if (IsFreeThreaded()) + if (IsFreeThreaded(unknownRef)) { - return unknownRef.As(); + return unknownRef; } else { - return new ObjectReferenceWithContext( - unknownRef.GetRef(), - Context.GetContextCallback(), - Context.GetContextToken()); + using (unknownRef) + { + return new ObjectReferenceWithContext( + unknownRef.GetRef(), + Context.GetContextCallback(), + Context.GetContextToken()); + } } // If we are free threaded, we do not need to keep track of context. // This can either be if the object implements IAgileObject or the free threaded marshaler. - unsafe bool IsFreeThreaded() - { - if (unknownRef.TryAs(typeof(ABI.WinRT.Interop.IAgileObject.Vftbl).GUID, out var agileRef) >= 0) - { - agileRef.Dispose(); - return true; - } - else if (unknownRef.TryAs(out var marshalRef) >= 0) - { - try - { - Guid iid_IUnknown = typeof(IUnknownVftbl).GUID; - Guid iid_unmarshalClass; - var marshaler = new ABI.WinRT.Interop.IMarshal(marshalRef); - marshaler.GetUnmarshalClass(&iid_IUnknown, IntPtr.Zero, MSHCTX.InProc, IntPtr.Zero, MSHLFLAGS.Normal, &iid_unmarshalClass); - if (iid_unmarshalClass == ABI.WinRT.Interop.IMarshal.IID_InProcFreeThreadedMarshaler.Value) - { - return true; - } - } - finally - { - marshalRef.Dispose(); - } - } - return false; - } + unsafe static bool IsFreeThreaded(IObjectReference unknownRef) + { + if (unknownRef.TryAs(ABI.WinRT.Interop.IAgileObject.IID, out var agilePtr) >= 0) + { + Marshal.Release(agilePtr); + return true; + } + else if (unknownRef.TryAs(ABI.WinRT.Interop.IMarshal.IID, out var marshalRef) >= 0) + { + using (marshalRef) + { + Guid iid_IUnknown = IUnknownVftbl.IID; + Guid iid_unmarshalClass; + Marshal.ThrowExceptionForHR(marshalRef.Vftbl.GetUnmarshalClass_0( + marshalRef.ThisPtr, &iid_IUnknown, IntPtr.Zero, MSHCTX.InProc, IntPtr.Zero, MSHLFLAGS.Normal, &iid_unmarshalClass)); + if (iid_unmarshalClass == ABI.WinRT.Interop.IMarshal.IID_InProcFreeThreadedMarshaler.Value) + { + return true; + } + } + } + return false; + } } public static void RegisterProjectionAssembly(Assembly assembly) => TypeNameSupport.RegisterProjectionAssembly(assembly); diff --git a/src/WinRT.Runtime/ComWrappersSupport.net5.cs b/src/WinRT.Runtime/ComWrappersSupport.net5.cs index aa684bc9b..c71198067 100644 --- a/src/WinRT.Runtime/ComWrappersSupport.net5.cs +++ b/src/WinRT.Runtime/ComWrappersSupport.net5.cs @@ -229,7 +229,7 @@ public unsafe static void Init( // otherwise the new instance will be used. Since the inner was composed // it should answer immediately without going through the outer. Either way // the reference count will go to the new instance. - Guid iid = typeof(IReferenceTrackerVftbl).GUID; + Guid iid = IReferenceTrackerVftbl.IID; int hr = Marshal.QueryInterface(objRef.ThisPtr, ref iid, out referenceTracker); if (hr != 0) { @@ -330,7 +330,7 @@ public unsafe static void Init(IObjectReference objRef, bool addRefFromTrackerSo { if (objRef.ReferenceTrackerPtr == IntPtr.Zero) { - Guid iid = typeof(IReferenceTrackerVftbl).GUID; + Guid iid = IReferenceTrackerVftbl.IID; int hr = Marshal.QueryInterface(objRef.ThisPtr, ref iid, out var referenceTracker); if (hr == 0) { @@ -434,7 +434,7 @@ private static unsafe bool IsRuntimeImplementedRCW(Type objType) private static object CreateObject(IObjectReference objRef) { - if (objRef.TryAs(out var inspectableRef) == 0) + if (objRef.TryAs(IInspectable.IID, out var inspectableRef) == 0) { IInspectable inspectable = new IInspectable(inspectableRef); @@ -448,7 +448,7 @@ private static object CreateObject(IObjectReference objRef) return ComWrappersSupport.GetTypedRcwFactory(runtimeClassName)(inspectable); } - else if (objRef.TryAs(out var weakRef) == 0) + else if (objRef.TryAs(ABI.WinRT.Interop.IWeakReference.IID, out var weakRef) == 0) { // IWeakReference is IUnknown-based, so implementations of it may not (and likely won't) implement // IInspectable. As a result, we need to check for them explicitly. diff --git a/src/WinRT.Runtime/Context.cs b/src/WinRT.Runtime/Context.cs index 17c89a794..be737520e 100644 --- a/src/WinRT.Runtime/Context.cs +++ b/src/WinRT.Runtime/Context.cs @@ -12,7 +12,7 @@ static class Context [DllImport("api-ms-win-core-com-l1-1-0.dll")] private static extern int CoGetObjectContext(ref Guid riid, out IntPtr ppv); - private static readonly Guid IID_ICallbackWithNoReentrancyToApplicationSTA = Guid.Parse("0A299774-3E4E-FC42-1D9D-72CEE105CA57"); + private static readonly Guid IID_ICallbackWithNoReentrancyToApplicationSTA = new(0x0A299774, 0x3E4E, 0xFC42, 0x1D, 0x9D, 0x72, 0xCE, 0xE1, 0x05, 0xCA, 0x57); public static IntPtr GetContextCallback() { diff --git a/src/WinRT.Runtime/ExceptionHelpers.cs b/src/WinRT.Runtime/ExceptionHelpers.cs index 395373253..d25dc67e9 100644 --- a/src/WinRT.Runtime/ExceptionHelpers.cs +++ b/src/WinRT.Runtime/ExceptionHelpers.cs @@ -56,30 +56,34 @@ static ExceptionHelpers() setRestrictedErrorInfo = Platform.GetProcAddress(winRTErrorModule); } } + } + + public static void ThrowExceptionForHR(int hr) + { + if (hr < 0) + { + Throw(hr); + } + + static void Throw(int hr) + { + Exception ex = GetExceptionForHR(hr, useGlobalErrorState: true, out bool restoredExceptionFromGlobalState); + if (restoredExceptionFromGlobalState) + { + ExceptionDispatchInfo.Capture(ex).Throw(); + } + else + { + throw ex; + } + } } - public static void ThrowExceptionForHR(int hr) - { - Exception ex = GetExceptionForHR(hr, useGlobalErrorState: true, out bool restoredExceptionFromGlobalState); - if (restoredExceptionFromGlobalState) - { - ExceptionDispatchInfo.Capture(ex).Throw(); - } - else if (ex is object) - { - throw ex; - } - } - - public static Exception GetExceptionForHR(int hr) => GetExceptionForHR(hr, false, out _); + public static Exception GetExceptionForHR(int hr) => hr >= 0 ? null : GetExceptionForHR(hr, false, out _); private static Exception GetExceptionForHR(int hr, bool useGlobalErrorState, out bool restoredExceptionFromGlobalState) { restoredExceptionFromGlobalState = false; - if (hr >= 0) - { - return null; - } ObjectReference iErrorInfo = null; IObjectReference restrictedErrorInfoToSave = null; diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index 3fa0063bc..e9e8aea4c 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -31,7 +31,7 @@ public static string GetSignature(Type type) var sigMethod = helperType.GetMethod("GetGuidSignature", BindingFlags.Static | BindingFlags.Public); if (sigMethod != null) { - return (string)sigMethod.Invoke(null, new Type[] { }); + return (string)sigMethod.Invoke(null, null); } } @@ -128,7 +128,7 @@ private static Guid encode_guid(Span data) #endif } - private static Guid wrt_pinterface_namespace = new Guid("d57af411-737b-c042-abae-878b1e16adee"); + private readonly static Guid wrt_pinterface_namespace = new(0xd57af411, 0x737b, 0xc042, 0xab, 0xae, 0x87, 0x8b, 0x1e, 0x16, 0xad, 0xee); public static Guid CreateIID(Type type) { diff --git a/src/WinRT.Runtime/IInspectable.cs b/src/WinRT.Runtime/IInspectable.cs index fbcadf9ef..eb17d7ed2 100644 --- a/src/WinRT.Runtime/IInspectable.cs +++ b/src/WinRT.Runtime/IInspectable.cs @@ -17,7 +17,9 @@ public enum TrustLevel [ObjectReferenceWrapper(nameof(_obj))] [Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")] public partial class IInspectable - { + { + internal static readonly Guid IID = new(0xAF86E2E0, 0xB12D, 0x4c6a, 0x9C, 0x5A, 0xD7, 0xAA, 0x65, 0x10, 0x1E, 0x90); + [Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")] public unsafe struct Vftbl { diff --git a/src/WinRT.Runtime/Interop/IAgileReference.net5.cs b/src/WinRT.Runtime/Interop/IAgileReference.net5.cs index 7d44e59b0..691b9f0ac 100644 --- a/src/WinRT.Runtime/Interop/IAgileReference.net5.cs +++ b/src/WinRT.Runtime/Interop/IAgileReference.net5.cs @@ -15,8 +15,8 @@ internal interface IAgileReference [WindowsRuntimeType] [Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")] public interface IAgileObject - { - public static readonly Guid IID = Guid.Parse("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90"); + { + public static readonly Guid IID = new(0x94ea2b94, 0xe9cc, 0x49e0, 0xc0, 0xff, 0xee, 0x64, 0xca, 0x8f, 0x5b, 0x90); } [WindowsRuntimeType] diff --git a/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs b/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs index e7fd6c92d..92e26362d 100644 --- a/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs +++ b/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs @@ -15,7 +15,7 @@ internal interface IAgileReference [WindowsRuntimeType] [Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")] public interface IAgileObject - { + { } [WindowsRuntimeType] @@ -113,7 +113,9 @@ public IObjectReference Resolve(Guid riid) [Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")] public class IAgileObject : global::WinRT.Interop.IAgileObject - { + { + internal static readonly Guid IID = new(0x94ea2b94, 0xe9cc, 0x49e0, 0xc0, 0xff, 0xee, 0x64, 0xca, 0x8f, 0x5b, 0x90); + [Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")] public struct Vftbl { diff --git a/src/WinRT.Runtime/Interop/IMarshal.cs b/src/WinRT.Runtime/Interop/IMarshal.cs index ff0054bfe..eda3c3601 100644 --- a/src/WinRT.Runtime/Interop/IMarshal.cs +++ b/src/WinRT.Runtime/Interop/IMarshal.cs @@ -31,7 +31,9 @@ namespace ABI.WinRT.Interop { [Guid("00000003-0000-0000-c000-000000000046")] internal class IMarshal - { + { + internal static readonly Guid IID = new(0x00000003, 0, 0, 0xc0, 0, 0, 0, 0, 0, 0, 0x46); + [DllImport("api-ms-win-core-com-l1-1-0.dll")] private static extern int CoCreateFreeThreadedMarshaler(IntPtr outer, out IntPtr marshalerPtr); diff --git a/src/WinRT.Runtime/Interop/IReferenceTracker.cs b/src/WinRT.Runtime/Interop/IReferenceTracker.cs index 4eb61e8bf..e49504a63 100644 --- a/src/WinRT.Runtime/Interop/IReferenceTracker.cs +++ b/src/WinRT.Runtime/Interop/IReferenceTracker.cs @@ -16,5 +16,7 @@ internal unsafe struct IReferenceTrackerVftbl private void* _ReleaseFromTrackerSource_5; public delegate* unmanaged[Stdcall] ReleaseFromTrackerSource { get => (delegate* unmanaged[Stdcall])_ReleaseFromTrackerSource_5; set => _ReleaseFromTrackerSource_5 = (void*)value; } private void* _PegFromTrackerSource_6; + + internal static readonly Guid IID = new(0x11D3B13A, 0x180E, 0x4789, 0xA8, 0xBE, 0x77, 0x12, 0x88, 0x28, 0x93, 0xE6); } } \ No newline at end of file diff --git a/src/WinRT.Runtime/Interop/IUnknownVftbl.cs b/src/WinRT.Runtime/Interop/IUnknownVftbl.cs index 8a81c4c0a..32a95f58c 100644 --- a/src/WinRT.Runtime/Interop/IUnknownVftbl.cs +++ b/src/WinRT.Runtime/Interop/IUnknownVftbl.cs @@ -16,6 +16,8 @@ public unsafe struct IUnknownVftbl public delegate* unmanaged[Stdcall] Release { get => (delegate* unmanaged[Stdcall])_Release; set => _Release = (void*)value; } public static IUnknownVftbl AbiToProjectionVftbl => ComWrappersSupport.IUnknownVftbl; - public static IntPtr AbiToProjectionVftblPtr => ComWrappersSupport.IUnknownVftblPtr; + public static IntPtr AbiToProjectionVftblPtr => ComWrappersSupport.IUnknownVftblPtr; + + internal static readonly Guid IID = new(0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46); } } diff --git a/src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs b/src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs index 42219959e..2706569ed 100644 --- a/src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs +++ b/src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs @@ -117,7 +117,9 @@ private static int Do_Abi_GetWeakReference(IntPtr thisPtr, IntPtr* weakReference [DynamicInterfaceCastableImplementation] [Guid("00000037-0000-0000-C000-000000000046")] internal unsafe interface IWeakReference : global::WinRT.Interop.IWeakReference - { + { + internal static readonly Guid IID = new(0x00000037, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46); + [Guid("00000037-0000-0000-C000-000000000046")] public struct Vftbl { diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index 3842b3b15..c9feaf9a1 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -48,7 +48,8 @@ public static unsafe MarshalString CreateMarshaler(string value) if (value == null) return null; var m = new MarshalString(); - Func dispose = () => { m.Dispose(); return false; }; + + bool success = false; try { m._gchandle = GCHandle.Alloc(value, GCHandleType.Pinned); @@ -58,12 +59,15 @@ public static unsafe MarshalString CreateMarshaler(string value) Marshal.ThrowExceptionForHR(Platform.WindowsCreateStringReference( (char*)chars, value.Length, (IntPtr*)m._header, (IntPtr*)handle)); }; + success = true; return m; } - catch (Exception) when (dispose()) + finally { - // Will never execute - return default; + if (!success) + { + m.Dispose(); + } } } @@ -140,7 +144,8 @@ public static unsafe MarshalerArray CreateMarshalerArray(string[] array) { return m; } - Func dispose = () => { m.Dispose(); return false; }; + + bool success = false; try { var length = array.Length; @@ -152,12 +157,15 @@ public static unsafe MarshalerArray CreateMarshalerArray(string[] array) m._marshalers[i] = MarshalString.CreateMarshaler(array[i]); elements[i] = MarshalString.GetAbi(m._marshalers[i]); }; + success = true; return m; } - catch (Exception) when (dispose()) + finally { - // Will never execute - return default; + if (!success) + { + m.Dispose(); + } } } @@ -205,13 +213,7 @@ public static unsafe (int length, IntPtr data) FromManagedArray(string[] array) } IntPtr data = IntPtr.Zero; int i = 0; - Func dispose = () => - { - DisposeAbiArray((i, data)); - i = 0; - data = IntPtr.Zero; - return false; - }; + bool success = false; try { var length = array.Length; @@ -220,14 +222,17 @@ public static unsafe (int length, IntPtr data) FromManagedArray(string[] array) for (i = 0; i < length; i++) { elements[i] = MarshalString.FromManaged(array[i]); - }; + } + success = true; + return (i, data); } - catch (Exception) when (dispose()) + finally { - // Will never execute - return default; + if (!success) + { + DisposeAbiArray((i, data)); + } } - return (i, data); } public static unsafe void CopyManagedArray(string[] array, IntPtr data) @@ -238,7 +243,7 @@ public static unsafe void CopyManagedArray(string[] array, IntPtr data) } DisposeAbiArrayElements((array.Length, data)); int i = 0; - Func dispose = () => { DisposeAbiArrayElements((i, data)); return false; }; + bool success = false; try { var length = array.Length; @@ -247,9 +252,14 @@ public static unsafe void CopyManagedArray(string[] array, IntPtr data) { elements[i] = MarshalString.FromManaged(array[i]); }; + success = true; } - catch (Exception) when (dispose()) + finally { + if (!success) + { + DisposeAbiArrayElements((i, data)); + } } } @@ -550,7 +560,8 @@ public void Dispose() { return m; } - Func dispose = () => { m.Dispose(); return false; }; + + bool success = false; try { int length = array.Length; @@ -565,12 +576,15 @@ public void Dispose() Marshaler.CopyAbi(m._marshalers[i], (IntPtr)element); element += abi_element_size; } + success = true; return m; } - catch (Exception) when (dispose()) + finally { - // Will never execute - return default; + if (!success) + { + m.Dispose(); + } } } @@ -628,13 +642,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) } IntPtr data = IntPtr.Zero; int i = 0; - Func dispose = () => - { - DisposeAbiArray((i, data)); - i = 0; - data = IntPtr.Zero; - return false; - }; + bool success = false; try { int length = array.Length; @@ -647,13 +655,16 @@ public static unsafe void CopyAbiArray(T[] array, object box) Marshaler.CopyManaged(array[i], (IntPtr)bytes); bytes += abi_element_size; } + success = true; + return (i, data); } - catch (Exception) when (dispose()) + finally { - // Will never execute - return default; + if (!success) + { + DisposeAbiArray((i, data)); + } } - return (i, data); } public static new unsafe void CopyManagedArray(T[] array, IntPtr data) @@ -664,7 +675,7 @@ public static unsafe void CopyAbiArray(T[] array, object box) } DisposeAbiArrayElements((array.Length, data)); int i = 0; - Func dispose = () => { DisposeAbiArrayElements((i, data)); return false; }; + bool success = false; try { int length = array.Length; @@ -676,9 +687,14 @@ public static unsafe void CopyAbiArray(T[] array, object box) Marshaler.CopyManaged(array[i], (IntPtr)bytes); bytes += abi_element_size; } + success = true; } - catch (Exception) when (dispose()) + finally { + if (!success) + { + DisposeAbiArrayElements((i, data)); + } } } @@ -736,7 +752,8 @@ public static unsafe MarshalerArray CreateMarshalerArray(T[] array, Func dispose = () => { m.Dispose(); return false; }; + + bool success = false; try { int length = array.Length; @@ -749,12 +766,15 @@ public static unsafe MarshalerArray CreateMarshalerArray(T[] array, Func dispose = () => - { - DisposeAbiArray((i, data)); - i = 0; - data = IntPtr.Zero; - return false; - }; + bool success = false; try { int length = array.Length; @@ -823,13 +837,16 @@ public static unsafe (int length, IntPtr data) FromManagedArray(T[] array, Func< { native[i] = fromManaged(array[i]); } + success = true; + return (i, data); } - catch (Exception) when (dispose()) + finally { - // Will never execute - return default; + if (!success) + { + DisposeAbiArray((i, data)); + } } - return (i, data); } public static unsafe void CopyManagedArray(T[] array, IntPtr data, Action copyManaged) @@ -840,7 +857,7 @@ public static unsafe void CopyManagedArray(T[] array, IntPtr data, Action dispose = () => { DisposeAbiArrayElements((i, data)); return false; }; + bool success = false; try { int length = array.Length; @@ -851,9 +868,14 @@ public static unsafe void CopyManagedArray(T[] array, IntPtr data, Action(); + return objRef.As(IInspectable.IID); } var publicType = o.GetType(); Type helperType = Projections.FindCustomHelperTypeMapping(publicType, true); @@ -1048,7 +1070,7 @@ public static IObjectReference CreateMarshaler(T o, bool unwrapObject = true) } using (var ccw = ComWrappersSupport.CreateCCWForObject(o)) { - return ccw.As(); + return ccw.As(IInspectable.IID); } } @@ -1062,7 +1084,7 @@ public static T FromAbi(IntPtr ptr) return default; } using var objRef = ObjectReference.FromAbi(ptr); - using var unknownObjRef = objRef.As(); + using var unknownObjRef = objRef.As(IUnknownVftbl.IID); if (unknownObjRef.IsReferenceToManagedObject) { return (T) ComWrappersSupport.FindObject(unknownObjRef.ThisPtr); diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 3102e26ad..e8cbd554d 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -402,7 +402,7 @@ internal static bool TryGetMarshalerTypeForProjectedRuntimeClass(IObjectRefer Type projectedType = typeof(T); if (projectedType == typeof(object)) { - if (objectReference.TryAs(out var inspectablePtr) == 0) + if (objectReference.TryAs(IInspectable.IID, out var inspectablePtr) == 0) { rwlock.EnterReadLock(); try diff --git a/src/WinRT.Runtime/TypeNameSupport.cs b/src/WinRT.Runtime/TypeNameSupport.cs index 7a73e671b..24157f781 100644 --- a/src/WinRT.Runtime/TypeNameSupport.cs +++ b/src/WinRT.Runtime/TypeNameSupport.cs @@ -250,7 +250,7 @@ private static bool TryAppendSimpleTypeName(Type type, StringBuilder builder, Ty { return false; } - builder.Append(">"); + builder.Append('>'); return true; } if (type == typeof(byte)) @@ -355,7 +355,7 @@ private static bool TryAppendTypeName(Type type, StringBuilder builder, TypeName builder.Append("Windows.Foundation.IReferenceArray`1<"); if (TryAppendTypeName(type.GetElementType(), builder, flags & ~TypeNameGenerationFlags.GenerateBoxedName)) { - builder.Append(">"); + builder.Append('>'); return true; } return true;