Skip to content

Commit e242424

Browse files
NativeAOT Unlock assignability comparison in reflection-free (#70726)
* NativeAOT Unlock assignability comparison in reflection-free Closes #69960 * Document support for `IsAssignableFrom` * Document support for `IsInstanceOfType` * Document `IsAssignableTo` * Add suggestion from Michal * Update src/coreclr/nativeaot/System.Private.DisabledReflection/src/Internal/Reflection/RuntimeTypeInfo.cs Co-authored-by: Michal Strehovský <[email protected]> * Remove whitespaces Co-authored-by: Michal Strehovský <[email protected]>
1 parent b3e606f commit e242424

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

src/coreclr/nativeaot/System.Private.DisabledReflection/src/Internal/Reflection/RuntimeTypeInfo.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,36 @@ protected override bool IsPrimitiveImpl()
202202
return RuntimeAugments.IsPrimitive(_typeHandle);
203203
}
204204

205+
public override bool IsAssignableFrom([NotNullWhen(true)] Type c)
206+
{
207+
if (c == null)
208+
return false;
209+
210+
if (object.ReferenceEquals(c, this))
211+
return true;
212+
213+
c = c.UnderlyingSystemType;
214+
215+
Type typeInfo = c;
216+
RuntimeTypeInfo toTypeInfo = this;
217+
218+
if (typeInfo is not RuntimeType)
219+
return false; // Desktop compat: If typeInfo is null, or implemented by a different Reflection implementation, return "false."
220+
221+
RuntimeTypeInfo fromTypeInfo = (RuntimeTypeInfo)typeInfo;
222+
223+
RuntimeTypeHandle toTypeHandle = toTypeInfo._typeHandle;
224+
RuntimeTypeHandle fromTypeHandle = fromTypeInfo._typeHandle;
225+
226+
if (RuntimeAugments.IsGenericTypeDefinition(toTypeHandle) || RuntimeAugments.IsGenericTypeDefinition(fromTypeHandle))
227+
throw new NotSupportedException(SR.Reflection_Disabled);
228+
229+
if (RuntimeAugments.IsAssignableFrom(toTypeHandle, fromTypeHandle))
230+
return true;
231+
232+
return false;
233+
}
234+
205235
internal static RuntimeTypeInfo GetRuntimeTypeInfo(RuntimeTypeHandle typeHandle)
206236
{
207237
return RuntimeTypeTable.Table.GetOrAdd(new RuntimeTypeHandleKey(typeHandle));

src/coreclr/nativeaot/docs/reflection-free-mode.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Think of:
3434
Reflection-free mode **supports a limited set of reflection APIs** that keep their expected semantics.
3535

3636
* `typeof(SomeType)` will return a `System.Type` that can be compared with results of other `typeof` expressions or results of `Object.GetType()` calls. The patterns commonly used in perf optimizations of generic code (e.g. `typeof(T) == typeof(byte)`) will work fine, and so will `obj.GetType() == typeof(SomeType)`.
37-
* Following APIs on `System.Type` work: `TypeHandle`, `UnderlyingSystemType`, `BaseType`, `IsByRefLike`, `IsValueType`, `GetTypeCode`, `GetHashCode`, `GetElementType`, `GetInterfaces`, `HasElementType`, `IsArray`, `IsByRef`, `IsPointer`, `IsPrimitive`.
37+
* Following APIs on `System.Type` work: `TypeHandle`, `UnderlyingSystemType`, `BaseType`, `IsByRefLike`, `IsValueType`, `GetTypeCode`, `GetHashCode`, `GetElementType`, `GetInterfaces`, `HasElementType`, `IsArray`, `IsByRef`, `IsPointer`, `IsPrimitive`, `IsAssignableFrom`, `IsAssignableTo`, `IsInstanceOfType`.
3838
* `Activator.CreateInstance<T>()` will work. The compiler statically analyzes and expands this to efficient code at compile time. No reflection is involved at runtime.
3939
* `Assembly.GetExecutingAssembly()` will return a `System.Reflection.Assembly` that can be compared with other runtime `Assembly` instances. This is mostly to make it possible to use the `NativeLibrary.SetDllImportResolver` API.
4040

0 commit comments

Comments
 (0)