Closed
Description
Description
I am trying to check if a type is or inherits from another. Type.IsAssignableTo(Type) and Type.IsSubclassOf(Type) are not on the list of working APIs, but Type.BaseType is.
The problem occurs when I try to get the base type of a type that doesn't have one.
Reproduction Steps
Classes.cs
public abstract class A { }
public class B : A { }
public class C : A { }
public abstract class Z : B { }
public class Y : Z { }
public class X : C { }
public static class Extensions
{
public static Boolean IsOrInheritsFrom(this Type type, Type expectedType)
{
Type? baseType = type;
while (baseType is not null)
{
if (baseType.Equals(expectedType))
return true;
baseType = baseType?.BaseType;
}
return false;
}
}
Program.cs
Dictionary<Type, String> types = new()
{
{ typeof(A), nameof(A) },
{ typeof(B), nameof(B) },
{ typeof(C), nameof(C) },
{ typeof(Z), nameof(Z) },
{ typeof(Y), nameof(Y) },
{ typeof(X), nameof(X) },
};
foreach (Type type in types.Keys)
foreach (Type type2 in types.Keys)
Console.WriteLine($"{types[type]} -> {type.IsOrInheritsFrom(type2)} <- {types[type2]}");
NativeAOTIssue.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
</ItemGroup>
</Project>
Compile the project using NativeAOT dotnet publish -r win-x64 /p:IlcDisableReflection=true
Execute native binary .\bin\Debug\net6.0\win-x64\publish\NativeAOTIssue.exe
Expected behavior
A -> True <- A
A -> False <- B
A -> False <- C
A -> False <- Z
A -> False <- Y
A -> False <- X
B -> True <- A
B -> True <- B
B -> False <- C
B -> False <- Z
B -> False <- Y
B -> False <- X
C -> True <- A
C -> False <- B
C -> True <- C
C -> False <- Z
C -> False <- Y
C -> False <- X
Z -> True <- A
Z -> True <- B
Z -> False <- C
Z -> True <- Z
Z -> False <- Y
Z -> False <- X
Y -> True <- A
Y -> True <- B
Y -> False <- C
Y -> True <- Z
Y -> True <- Y
Y -> False <- X
X -> True <- A
X -> False <- B
X -> True <- C
X -> False <- Z
X -> False <- Y
X -> True <- X
Actual behavior
A -> True <- A
Unhandled Exception: EETypeRva:0x0021E3B8: Arg_NullReferenceException
at Internal.Runtime.MethodTable.get_Kind() + 0xf
at Internal.Runtime.MethodTable.get_IsGenericTypeDefinition() + 0x18
at System.EETypePtr.get_IsGenericTypeDefinition() + 0x1b
at Internal.Runtime.Augments.RuntimeAugments.TryGetBaseType(RuntimeTypeHandle, RuntimeTypeHandle&) + 0x45
at Internal.Reflection.RuntimeTypeInfo.get_BaseType() + 0x29
at Extensions.IsOrInheritsFrom(Type, Type) + 0x91
at Program.<Main>$(String[]) + 0x3bc
at NativeAOTIssue!<BaseAddress>+0x1c6907
at NativeAOTIssue!<BaseAddress>+0x1c6995
Regression?
No response
Known Workarounds
No response
Configuration
.NET: 6.0
OS: Windows 10 21H2
Arch: x64
Other information
No response