Nullable: System.Runtime.InteropServices.CustomMarshalers/WindowsRuntime (#23930)
[platform/upstream/coreclr.git] / src / System.Private.CoreLib / src / System / Runtime / InteropServices / WindowsRuntime / RuntimeClass.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*============================================================
6 **
7 **
8 **
9 ** RuntimeClass is the base class of all WinRT types
10 **
11 ** 
12 ===========================================================*/
13
14 #nullable enable
15 using System.Runtime.CompilerServices;
16
17 namespace System.Runtime.InteropServices.WindowsRuntime
18 {
19     // Local definition of Windows.Foundation.IStringable
20     [ComImport]
21     [Guid("96369f54-8eb6-48f0-abce-c1b211e627c3")]
22     [WindowsRuntimeImport]
23     internal interface IStringable
24     {
25         string ToString();
26     }
27
28     internal class IStringableHelper
29     {
30         internal static string? ToString(object obj)
31         {
32             if (obj is IGetProxyTarget proxy)
33                 obj = proxy.GetTarget();
34
35             // Check whether the type implements IStringable.
36             if (obj is IStringable stringableType)
37             {
38                 return stringableType.ToString();
39             }
40
41             return obj.ToString();
42         }
43     }
44
45     //
46     // Base class for every WinRT class
47     // We'll make it a ComImport and WindowsRuntimeImport in the type loader
48     // as C# compiler won't allow putting code in ComImport type
49     //
50     internal abstract class RuntimeClass : __ComObject
51     {
52         //
53         // Support for ToString/GetHashCode/Equals override
54         //        
55         [MethodImpl(MethodImplOptions.InternalCall)]
56         internal extern IntPtr GetRedirectedGetHashCodeMD();
57
58         [MethodImpl(MethodImplOptions.InternalCall)]
59         internal extern int RedirectGetHashCode(IntPtr pMD);
60
61         public override int GetHashCode()
62         {
63             IntPtr pMD = GetRedirectedGetHashCodeMD();
64             if (pMD == IntPtr.Zero)
65                 return base.GetHashCode();
66             return RedirectGetHashCode(pMD);
67         }
68
69         [MethodImpl(MethodImplOptions.InternalCall)]
70         internal extern IntPtr GetRedirectedToStringMD();
71
72         [MethodImpl(MethodImplOptions.InternalCall)]
73         internal extern string RedirectToString(IntPtr pMD);
74
75         public override string ToString()
76         {
77             // Check whether the type implements IStringable.
78             if (this is IStringable stringableType)
79             {
80                 return stringableType.ToString();
81             }
82             else
83             {
84                 IntPtr pMD = GetRedirectedToStringMD();
85
86                 if (pMD == IntPtr.Zero)
87                     return base.ToString();
88
89                 return RedirectToString(pMD);
90             }
91         }
92
93         [MethodImpl(MethodImplOptions.InternalCall)]
94         internal extern IntPtr GetRedirectedEqualsMD();
95
96         [MethodImpl(MethodImplOptions.InternalCall)]
97         internal extern bool RedirectEquals(object? obj, IntPtr pMD);
98
99         public override bool Equals(object? obj)
100         {
101             IntPtr pMD = GetRedirectedEqualsMD();
102             if (pMD == IntPtr.Zero)
103                 return base.Equals(obj);
104             return RedirectEquals(obj, pMD);
105         }
106     }
107 }