dotnet/runtime

Some System.Reflection.Emit implementations of `Type.IsByRefLike` still throw `NotSupportedException`: "Derived classes must provide an implementation"

Open

#91,532 opened on Sep 4, 2023

View on GitHub
 (6 comments) (0 reactions) (0 assignees)C# (5,445 forks)batch import
area-System.Reflection.Emitbughelp wanted

Repository metrics

Stars
 (17,886 stars)
PR merge metrics
 (Avg merge 12d 11h) (661 merged PRs in 30d)

Description

Description

Certain System.Reflection.Emit (SRE) subclasses of Type appear to be missing an implementation for the Type.IsByRefLike property. When queried, a NotSupportedException ("Derived classes must provide an implementation") gets thrown when they should probably just return false.

I've so far found two such types that both seem to involve generics: System.Reflection.Emit.TypeBuilderInstantiation and System.Reflection.Emit.SymbolType.

Could it be that these two types were overlooked back in https://github.com/dotnet/runtime/pull/34846?

Reproduction Steps

Here is one code example that reproduces the problem for System.Reflection.Emit.TypeBuilderInstantiation:

var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("A"), AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("A");
var genericTypeBuilder = moduleBuilder.DefineType("C", TypeAttributes.Class);
_ = genericTypeBuilder.DefineGenericParameters("T");
var closedGenericTypeBuilder = genericTypeBuilder.MakeGenericType(typeof(object));
Console.WriteLine(closedGenericTypeBuilder.GetType().FullName);
Console.WriteLine(closedGenericTypeBuilder.IsByRefLike);

(I haven't yet been able to create a short code repro for System.Reflection.Emit.SymbolType, but will add one if I can figure it out.)

Expected behavior

Prints the following to the console:

System.Reflection.Emit.TypeBuilderInstantiation
False

Actual behavior

Prints the following to the console:

System.Reflection.Emit.TypeBuilderInstantiation
Unhandled exception. System.NotSupportedException: Derived classes must provide an implementation.
   at System.Type.get_IsByRefLike()
   at Program.Main ...

The exception is caused by the IsByRefLike query in the last line of code.

Regression?

I don't think this is a regression, since the same error also occurs on older .NET runtimes (e. g. .NET Core 3.1). It appears like this simply hasn't been implemented yet at all.

Known Workarounds

I don't know of any workaround short of wrapping IsByRefLike queries in an extension method that catches the exception and converts it to false, then calling that extension method instead of using IsByRefLike directly:

static bool IsByRefLikeSafe(this Type type)
{
    try
    {
        return type.IsByRefLike;
    }
    catch (NotSupportedException)
    {
        return false;
    }
}

Configuration

  • I've run the code repro on the following runtimes:
    • .NET Core 3.1
    • .NET 6
    • .NET 7
  • OS: Windows 11 Pro (22H2), build 22621.2134
  • Architecture: x64

Other information

No response

Contributor guide