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+ using System ;
6+ using System . Collections ;
7+ using System . Collections . Generic ;
8+ using System . Numerics ;
9+ using System . Runtime . CompilerServices ;
10+ using System . Runtime . Intrinsics ;
11+
12+ public partial class Program
13+ {
14+ public static void TestIsAssignableFrom ( )
15+ {
16+ // Primitive types
17+ IsTrue ( typeof ( void ) . IsAssignableFrom ( typeof ( void ) ) ) ;
18+ IsTrue ( typeof ( byte ) . IsAssignableFrom ( typeof ( byte ) ) ) ;
19+ IsTrue ( typeof ( int ) . IsAssignableFrom ( typeof ( int ) ) ) ;
20+ IsTrue ( typeof ( float ) . IsAssignableFrom ( typeof ( float ) ) ) ;
21+ IsTrue ( typeof ( double ) . IsAssignableFrom ( typeof ( double ) ) ) ;
22+ IsTrue ( typeof ( byte * ) . IsAssignableFrom ( typeof ( byte * ) ) ) ;
23+ IsTrue ( typeof ( sbyte * ) . IsAssignableFrom ( typeof ( byte * ) ) ) ;
24+ IsTrue ( typeof ( void * ) . IsAssignableFrom ( typeof ( void * ) ) ) ;
25+ IsTrue ( typeof ( byte * * ) . IsAssignableFrom ( typeof ( byte * * ) ) ) ;
26+ IsFalse ( typeof ( byte ) . IsAssignableFrom ( typeof ( sbyte ) ) ) ;
27+ IsFalse ( typeof ( sbyte ) . IsAssignableFrom ( typeof ( byte ) ) ) ;
28+ IsFalse ( typeof ( int ) . IsAssignableFrom ( typeof ( long ) ) ) ;
29+ IsFalse ( typeof ( int ) . IsAssignableFrom ( typeof ( void ) ) ) ;
30+ IsFalse ( typeof ( void ) . IsAssignableFrom ( typeof ( long ) ) ) ;
31+ IsFalse ( typeof ( long ) . IsAssignableFrom ( typeof ( int ) ) ) ;
32+ IsFalse ( typeof ( float ) . IsAssignableFrom ( typeof ( double ) ) ) ;
33+ IsFalse ( typeof ( double ) . IsAssignableFrom ( typeof ( float ) ) ) ;
34+ IsFalse ( typeof ( double ) . IsAssignableFrom ( typeof ( long ) ) ) ;
35+ IsFalse ( typeof ( int ) . IsAssignableFrom ( typeof ( float ) ) ) ;
36+ IsFalse ( typeof ( sbyte * ) . IsAssignableFrom ( typeof ( ulong * ) ) ) ;
37+ IsFalse ( typeof ( sbyte * ) . IsAssignableFrom ( typeof ( void * ) ) ) ;
38+ IsFalse ( typeof ( void * ) . IsAssignableFrom ( typeof ( ulong * ) ) ) ;
39+ IsFalse ( typeof ( sbyte * ) . IsAssignableFrom ( typeof ( IntPtr ) ) ) ;
40+ IsFalse ( typeof ( IntPtr ) . IsAssignableFrom ( typeof ( sbyte * ) ) ) ;
41+ IsFalse ( typeof ( byte * * ) . IsAssignableFrom ( typeof ( byte * ) ) ) ;
42+ IsFalse ( typeof ( byte * ) . IsAssignableFrom ( typeof ( byte * * ) ) ) ;
43+
44+ // Nullable
45+ IsTrue ( typeof ( int ? ) . IsAssignableFrom ( typeof ( int ) ) ) ;
46+ IsTrue ( typeof ( int ? ) . IsAssignableFrom ( typeof ( int ? ) ) ) ;
47+ IsTrue ( typeof ( GenericStruct1 < int > ? ) . IsAssignableFrom ( typeof ( GenericStruct1 < int > ? ) ) ) ;
48+ IsTrue ( typeof ( GenericStruct1 < string > ? ) . IsAssignableFrom ( typeof ( GenericStruct1 < string > ? ) ) ) ;
49+ IsTrue ( typeof ( SimpleEnum_int ? ) . IsAssignableFrom ( typeof ( SimpleEnum_int ? ) ) ) ;
50+ IsFalse ( typeof ( int ) . IsAssignableFrom ( typeof ( int ? ) ) ) ;
51+ IsFalse ( typeof ( uint ? ) . IsAssignableFrom ( typeof ( int ? ) ) ) ;
52+ IsFalse ( typeof ( int ? ) . IsAssignableFrom ( typeof ( uint ? ) ) ) ;
53+ IsFalse ( typeof ( SimpleEnum_uint ? ) . IsAssignableFrom ( typeof ( SimpleEnum_int ? ) ) ) ;
54+ IsFalse ( typeof ( SimpleEnum_int ? ) . IsAssignableFrom ( typeof ( SimpleEnum_uint ? ) ) ) ;
55+ IsFalse ( typeof ( GenericStruct1 < int > ? ) . IsAssignableFrom ( typeof ( GenericStruct1 < uint > ? ) ) ) ;
56+
57+ // Enums
58+ IsTrue ( typeof ( SimpleEnum_int ) . IsAssignableFrom ( typeof ( SimpleEnum_int ) ) ) ;
59+ IsTrue ( typeof ( SimpleEnum_int ? ) . IsAssignableFrom ( typeof ( SimpleEnum_int ? ) ) ) ;
60+ IsTrue ( typeof ( SimpleEnum_uint ) . IsAssignableFrom ( typeof ( SimpleEnum_uint ) ) ) ;
61+ IsTrue ( typeof ( SimpleEnum_byte ) . IsAssignableFrom ( typeof ( SimpleEnum_byte ) ) ) ;
62+ IsTrue ( typeof ( ValueType ) . IsAssignableFrom ( typeof ( SimpleEnum_uint ) ) ) ;
63+ IsFalse ( typeof ( SimpleEnum_int ) . IsAssignableFrom ( typeof ( SimpleEnum_uint ) ) ) ;
64+ IsFalse ( typeof ( SimpleEnum_uint ) . IsAssignableFrom ( typeof ( SimpleEnum_int ) ) ) ;
65+ IsFalse ( typeof ( SimpleEnum_uint ) . IsAssignableFrom ( typeof ( SimpleEnum_byte ) ) ) ;
66+ IsFalse ( typeof ( SimpleEnum_byte ) . IsAssignableFrom ( typeof ( SimpleEnum_uint ) ) ) ;
67+ IsFalse ( typeof ( SimpleEnum_byte ) . IsAssignableFrom ( typeof ( byte ) ) ) ;
68+ IsFalse ( typeof ( byte ) . IsAssignableFrom ( typeof ( SimpleEnum_byte ) ) ) ;
69+ IsFalse ( typeof ( SimpleEnum_int ) . IsAssignableFrom ( typeof ( int ) ) ) ;
70+ IsFalse ( typeof ( int ) . IsAssignableFrom ( typeof ( SimpleEnum_int ) ) ) ;
71+ IsFalse ( typeof ( SimpleEnum_uint ) . IsAssignableFrom ( typeof ( float ) ) ) ;
72+ IsFalse ( typeof ( float ) . IsAssignableFrom ( typeof ( SimpleEnum_uint ) ) ) ;
73+ IsFalse ( typeof ( SimpleEnum_uint ) . IsAssignableFrom ( typeof ( ValueType ) ) ) ;
74+
75+ // Covariance/Contravariance
76+ IsTrue ( typeof ( IEnumerable < object > ) . IsAssignableFrom ( typeof ( List < string > ) ) ) ;
77+ IsTrue ( typeof ( IEnumerable < ClassA > ) . IsAssignableFrom ( typeof ( List < ClassB > ) ) ) ;
78+ IsTrue ( typeof ( IEnumerable < ClassA > ) . IsAssignableFrom ( typeof ( IList < ClassB > ) ) ) ;
79+ IsTrue ( typeof ( IEnumerable < ClassA > ) . IsAssignableFrom ( typeof ( IList < ClassD > ) ) ) ;
80+ IsTrue ( typeof ( IEnumerable < ClassA > ) . IsAssignableFrom ( typeof ( IList < ClassA > ) ) ) ;
81+ IsTrue ( typeof ( Action < string > ) . IsAssignableFrom ( typeof ( Action < object > ) ) ) ;
82+ IsTrue ( typeof ( object [ ] ) . IsAssignableFrom ( typeof ( string [ ] ) ) ) ;
83+ IsTrue ( typeof ( object [ , ] ) . IsAssignableFrom ( typeof ( string [ , ] ) ) ) ;
84+ IsTrue ( typeof ( SimpleEnum_int [ , ] ) . IsAssignableFrom ( typeof ( SimpleEnum_uint [ , ] ) ) ) ;
85+ IsFalse ( typeof ( string [ , ] ) . IsAssignableFrom ( typeof ( object [ , ] ) ) ) ;
86+ IsFalse ( typeof ( object [ , ] ) . IsAssignableFrom ( typeof ( string [ , , ] ) ) ) ;
87+ IsFalse ( typeof ( IDictionary < ClassA , int > ) . IsAssignableFrom ( typeof ( IDictionary < ClassB , int > ) ) ) ;
88+ IsFalse ( typeof ( IDictionary < ClassA , int > ) . IsAssignableFrom ( typeof ( Dictionary < ClassB , int > ) ) ) ;
89+ IsFalse ( typeof ( Action < object > ) . IsAssignableFrom ( typeof ( Action < string > ) ) ) ;
90+ IsFalse ( typeof ( Action < object > ) . IsAssignableFrom ( typeof ( Action < Guid > ) ) ) ;
91+ IsFalse ( typeof ( List < string > ) . IsAssignableFrom ( typeof ( IEnumerable < object > ) ) ) ;
92+ IsFalse ( typeof ( Action < Guid > ) . IsAssignableFrom ( typeof ( Action < object > ) ) ) ;
93+ IsFalse ( typeof ( List < ClassB > ) . IsAssignableFrom ( typeof ( IEnumerable < ClassA > ) ) ) ;
94+ IsFalse ( typeof ( IList < ClassB > ) . IsAssignableFrom ( typeof ( IEnumerable < ClassA > ) ) ) ;
95+ IsFalse ( typeof ( IList < ClassD > ) . IsAssignableFrom ( typeof ( IEnumerable < ClassA > ) ) ) ;
96+ IsFalse ( typeof ( IList < ClassA > ) . IsAssignableFrom ( typeof ( IEnumerable < ClassA > ) ) ) ;
97+
98+ // Arrays
99+ IsTrue ( typeof ( byte [ ] ) . IsAssignableFrom ( typeof ( sbyte [ ] ) ) ) ;
100+ IsTrue ( typeof ( sbyte [ ] ) . IsAssignableFrom ( typeof ( byte [ ] ) ) ) ;
101+ IsTrue ( typeof ( short [ ] ) . IsAssignableFrom ( typeof ( ushort [ ] ) ) ) ;
102+ IsTrue ( typeof ( ushort [ ] ) . IsAssignableFrom ( typeof ( short [ ] ) ) ) ;
103+ IsTrue ( typeof ( int [ ] ) . IsAssignableFrom ( typeof ( uint [ ] ) ) ) ;
104+ IsTrue ( typeof ( uint [ ] ) . IsAssignableFrom ( typeof ( int [ ] ) ) ) ;
105+ IsTrue ( typeof ( long [ ] ) . IsAssignableFrom ( typeof ( ulong [ ] ) ) ) ;
106+ IsTrue ( typeof ( ulong [ ] ) . IsAssignableFrom ( typeof ( long [ ] ) ) ) ;
107+ IsTrue ( typeof ( long [ , ] ) . IsAssignableFrom ( typeof ( ulong [ , ] ) ) ) ;
108+ IsTrue ( typeof ( ulong [ , , ] ) . IsAssignableFrom ( typeof ( long [ , , ] ) ) ) ;
109+ IsTrue ( typeof ( Struct1 [ ] ) . IsAssignableFrom ( typeof ( Struct1 [ ] ) ) ) ;
110+ IsFalse ( typeof ( int [ ] ) . IsAssignableFrom ( typeof ( byte [ ] ) ) ) ;
111+ IsFalse ( typeof ( int [ ] ) . IsAssignableFrom ( typeof ( sbyte [ ] ) ) ) ;
112+ IsFalse ( typeof ( int [ ] ) . IsAssignableFrom ( typeof ( short [ ] ) ) ) ;
113+ IsFalse ( typeof ( int [ ] ) . IsAssignableFrom ( typeof ( ushort [ ] ) ) ) ;
114+ IsFalse ( typeof ( int [ ] ) . IsAssignableFrom ( typeof ( float [ ] ) ) ) ;
115+ IsFalse ( typeof ( int [ ] ) . IsAssignableFrom ( typeof ( double [ ] ) ) ) ;
116+ IsFalse ( typeof ( long [ ] ) . IsAssignableFrom ( typeof ( double [ ] ) ) ) ;
117+ IsFalse ( typeof ( Struct1 [ ] ) . IsAssignableFrom ( typeof ( Struct2 [ ] ) ) ) ;
118+ IsFalse ( typeof ( Struct1 [ ] ) . IsAssignableFrom ( typeof ( GenericStruct1 < int > [ ] ) ) ) ;
119+ IsFalse ( typeof ( GenericStruct1 < uint > [ ] ) . IsAssignableFrom ( typeof ( GenericStruct1 < int > [ ] ) ) ) ;
120+
121+ // Misc
122+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( byte ) ) ) ;
123+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( int ) ) ) ;
124+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( float ) ) ) ;
125+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( SimpleEnum_uint ) ) ) ;
126+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( IDisposable ) ) ) ;
127+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( IDictionary < string , string > ) ) ) ;
128+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( List < int > ) ) ) ;
129+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( List < > ) ) ) ;
130+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( Action < > ) ) ) ;
131+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( Action < int > ) ) ) ;
132+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( Vector128 < float > ) ) ) ;
133+ IsTrue ( typeof ( object ) . IsAssignableFrom ( typeof ( Vector256 < int > ) ) ) ;
134+ IsTrue ( typeof ( ClassA ) . IsAssignableFrom ( typeof ( ClassA ) ) ) ;
135+ IsTrue ( typeof ( ClassA ) . IsAssignableFrom ( typeof ( ClassB ) ) ) ;
136+ IsTrue ( typeof ( ClassA ) . IsAssignableFrom ( typeof ( ClassC ) ) ) ;
137+ IsTrue ( typeof ( decimal ) . IsAssignableFrom ( typeof ( decimal ) ) ) ;
138+ IsTrue ( typeof ( Struct1 ) . IsAssignableFrom ( typeof ( Struct1 ) ) ) ;
139+ IsTrue ( typeof ( IDisposable ) . IsAssignableFrom ( typeof ( Struct3 ) ) ) ;
140+ IsTrue ( typeof ( Dictionary < , > ) . IsAssignableFrom ( typeof ( Dictionary < , > ) ) ) ;
141+ IsTrue ( typeof ( IDictionary < , > ) . IsAssignableFrom ( typeof ( IDictionary < , > ) ) ) ;
142+ IsTrue ( typeof ( GenericStruct1 < > ) . IsAssignableFrom ( typeof ( GenericStruct1 < > ) ) ) ;
143+ IsTrue ( typeof ( GenericStruct1 < int > ) . IsAssignableFrom ( typeof ( GenericStruct1 < int > ) ) ) ;
144+ IsTrue ( typeof ( GenericStruct1 < string > ) . IsAssignableFrom ( typeof ( GenericStruct1 < string > ) ) ) ;
145+ IsFalse ( typeof ( byte ) . IsAssignableFrom ( typeof ( IDisposable ) ) ) ;
146+ IsFalse ( typeof ( IDisposable ) . IsAssignableFrom ( typeof ( IEnumerable ) ) ) ;
147+ IsFalse ( typeof ( IDictionary < string , string > ) . IsAssignableFrom ( typeof ( IDictionary < string , int > ) ) ) ;
148+ IsFalse ( typeof ( List < int > ) . IsAssignableFrom ( typeof ( IList < int > ) ) ) ;
149+ IsFalse ( typeof ( List < > ) . IsAssignableFrom ( typeof ( List < IDisposable > ) ) ) ;
150+ IsFalse ( typeof ( Action < > ) . IsAssignableFrom ( typeof ( Action < int > ) ) ) ;
151+ IsFalse ( typeof ( Action < > ) . IsAssignableFrom ( typeof ( Func < int > ) ) ) ;
152+ IsFalse ( typeof ( Action ) . IsAssignableFrom ( typeof ( CustomAction ) ) ) ;
153+ IsFalse ( typeof ( Action < int > ) . IsAssignableFrom ( typeof ( void ) ) ) ;
154+ IsFalse ( typeof ( ClassB ) . IsAssignableFrom ( typeof ( ClassD ) ) ) ;
155+ IsFalse ( typeof ( Dictionary < , > ) . IsAssignableFrom ( typeof ( Dictionary < int , int > ) ) ) ;
156+ IsFalse ( typeof ( GenericStruct1 < ClassA > ) . IsAssignableFrom ( typeof ( GenericStruct1 < ClassB > ) ) ) ;
157+ IsFalse ( typeof ( Struct1 ) . IsAssignableFrom ( typeof ( Struct2 ) ) ) ;
158+ IsFalse ( typeof ( GenericStruct1 < > ) . IsAssignableFrom ( typeof ( GenericStruct2 < > ) ) ) ;
159+ IsFalse ( typeof ( GenericStruct1 < int > ) . IsAssignableFrom ( typeof ( GenericStruct2 < int > ) ) ) ;
160+ IsFalse ( typeof ( object ) . IsAssignableFrom ( typeof ( byte * ) ) ) ;
161+ IsFalse ( typeof ( object ) . IsAssignableFrom ( typeof ( byte * * ) ) ) ;
162+ IsFalse ( typeof ( Vector128 < double > ) . IsAssignableFrom ( typeof ( Vector128 < float > ) ) ) ;
163+ IsFalse ( typeof ( Vector128 < float > ) . IsAssignableFrom ( typeof ( Vector128 < int > ) ) ) ;
164+ IsFalse ( typeof ( Vector128 < int > ) . IsAssignableFrom ( typeof ( Vector128 < float > ) ) ) ;
165+ IsFalse ( typeof ( Vector4 ) . IsAssignableFrom ( typeof ( Vector128 < float > ) ) ) ;
166+ IsFalse ( typeof ( Vector128 < float > ) . IsAssignableFrom ( typeof ( Vector4 ) ) ) ;
167+ IsFalse ( typeof ( Vector128 < float > ) . IsAssignableFrom ( typeof ( Vector < float > ) ) ) ;
168+ IsFalse ( typeof ( Vector256 < float > ) . IsAssignableFrom ( typeof ( Vector < float > ) ) ) ;
169+
170+ // System.__Canon
171+ IsTrue ( IsAssignableFrom < KeyValuePair < IDisposable , IDisposable > , KeyValuePair < IDisposable , IDisposable > > ( ) ) ;
172+ IsTrue ( IsAssignableFrom < KeyValuePair < IDisposable , object > , KeyValuePair < IDisposable , object > > ( ) ) ;
173+ IsTrue ( IsAssignableFrom < IDictionary < IDisposable , IDisposable > , IDictionary < IDisposable , IDisposable > > ( ) ) ;
174+ IsTrue ( IsAssignableFrom < IDictionary < IDisposable , object > , IDictionary < IDisposable , object > > ( ) ) ;
175+ IsTrue ( IsAssignableFrom < Dictionary < IDisposable , IDisposable > , Dictionary < IDisposable , IDisposable > > ( ) ) ;
176+ IsTrue ( IsAssignableFrom < Dictionary < IDisposable , object > , Dictionary < IDisposable , object > > ( ) ) ;
177+ IsTrue ( IsAssignableFrom < KeyValuePair < int , int > , KeyValuePair < int , int > > ( ) ) ;
178+ IsTrue ( IsAssignableFrom < KeyValuePair < IEnumerable < int > , IEnumerable < int > > , KeyValuePair < IEnumerable < int > , IEnumerable < int > > > ( ) ) ;
179+ IsFalse ( IsAssignableFrom < KeyValuePair < IDisposable , IDisposable > , KeyValuePair < IDisposable , object > > ( ) ) ;
180+ IsFalse ( IsAssignableFrom < KeyValuePair < IDisposable , int > , KeyValuePair < IDisposable , object > > ( ) ) ;
181+ IsFalse ( IsAssignableFrom < IDictionary < IDisposable , IDisposable > , IDictionary < IDisposable , object > > ( ) ) ;
182+ IsFalse ( IsAssignableFrom < IDictionary < IDisposable , int > , IDictionary < IDisposable , object > > ( ) ) ;
183+ IsFalse ( IsAssignableFrom < Dictionary < IDisposable , IDisposable > , Dictionary < IDisposable , object > > ( ) ) ;
184+ IsFalse ( IsAssignableFrom < Dictionary < IDisposable , int > , Dictionary < IDisposable , object > > ( ) ) ;
185+ IsFalse ( IsAssignableFrom < KeyValuePair < int , int > , KeyValuePair < int , object > > ( ) ) ;
186+ IsFalse ( IsAssignableFrom < KeyValuePair < IEnumerable < int > , IEnumerable < int > > , KeyValuePair < IEnumerable < int > , IEnumerable < uint > > > ( ) ) ;
187+ }
188+
189+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
190+ static bool IsAssignableFrom < TTo , TTFrom > ( ) => typeof ( TTo ) . IsAssignableFrom ( typeof ( TTFrom ) ) ;
191+ }
192+
193+ public struct Struct1
194+ {
195+ public int field1 ;
196+ }
197+
198+ public struct Struct2
199+ {
200+ public int field1 ;
201+ }
202+
203+ public struct Struct3 : IDisposable
204+ {
205+ public int field1 ;
206+ public void Dispose ( ) { }
207+ }
208+
209+ public struct GenericStruct1 < T >
210+ {
211+ public T field ;
212+ }
213+
214+ public struct GenericStruct2 < T >
215+ {
216+ public T field ;
217+ }
218+
219+ public enum SimpleEnum_byte : byte
220+ {
221+ A , B , C
222+ }
223+
224+ public enum SimpleEnum_int : int
225+ {
226+ A , B , C
227+ }
228+
229+ public enum SimpleEnum_uint : uint
230+ {
231+ D , E
232+ }
233+
234+ public class ClassA
235+ {
236+ }
237+
238+ public class ClassB : ClassA
239+ {
240+ }
241+
242+ public class ClassC : ClassB
243+ {
244+ }
245+
246+ public class ClassD : ClassA
247+ {
248+ }
249+
250+ public delegate void CustomAction ( ) ;
0 commit comments