dotnet/runtime

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

Open

#91,532 建立於 2023年9月4日

在 GitHub 查看
 (6 留言) (0 反應) (0 負責人)C# (5,445 fork)batch import
area-System.Reflection.Emitbughelp wanted

倉庫指標

Star
 (17,886 star)
PR 合併指標
 (平均合併 12天 11小時) (30 天內合併 661 個 PR)

描述

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

貢獻者指南