猿问

从 C# 8 中的 System.Reflection.Metadata 获取接口可为 null

我目前正在制作一个工具来处理新的 C# 8 可空上下文。基本上是我的项目的 API 审批工具。


我正在使用 System.Reflection.Metadata,只是在一种情况下提取元数据时遇到问题。


public class DerivedNullableBase2 : MyBase<MyBase<string?>?>

{

}

我正在尝试为我正在创建的 API 生成器工具获取 C#8 可空上下文。因此,对于上面的类,会生成以下 IL:


.class auto ansi nested public beforefieldinit DerivedNullableInterface2

       extends [netstandard]System.Object

       implements class [netstandard]System.Collections.Generic.IEnumerable`1<class [netstandard]System.Collections.Generic.IEnumerable`1<string>>,

                  [netstandard]System.Collections.IEnumerable

{

  .interfaceimpl type class [netstandard]System.Collections.Generic.IEnumerable`1<class [netstandard]System.Collections.Generic.IEnumerable`1<string>>

  .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 00 02 00 00 ) 

} // end of class DerivedNullableInterface2

我想提取其中包含的 NullableAttribute 以确定通用接口的可为空上下文。


我尝试通过 TypeDefinition 和 InterfaceImplementation 获取属性,但似乎不存在,在这种情况下我将如何提取 NullableAttribute ?


ABOUTYOU
浏览 165回答 1
1回答

皈依舞

以下代码将从使用 C# 8 语法NullableAttribute中提取 a InterfaceImplementation。using var peReader = new PEReader(File.OpenRead(Assembly.GetExecutingAssembly().Location));var mdReader = peReader.GetMetadataReader();foreach (var attributeHandle in mdReader.CustomAttributes){    var attribute = mdReader.GetCustomAttribute(attributeHandle);    var ctorHandle = attribute.Constructor;    EntityHandle attributeTypeHandle = ctorHandle.Kind switch    {        HandleKind.MethodDefinition => mdReader.GetMethodDefinition((MethodDefinitionHandle)ctorHandle).GetDeclaringType(),        HandleKind.MemberReference => mdReader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent,        _ => throw new InvalidOperationException(),    };    StringHandle attributeTypeNameHandle = attributeTypeHandle.Kind switch    {        HandleKind.TypeDefinition => mdReader.GetTypeDefinition((TypeDefinitionHandle)attributeTypeHandle).Name,        HandleKind.TypeReference => mdReader.GetTypeReference((TypeReferenceHandle)attributeTypeHandle).Name,        _ => throw new InvalidOperationException(),    };    if (mdReader.StringComparer.Equals(attributeTypeNameHandle, "NullableAttribute"))    {        Console.WriteLine(attribute.Parent.Kind);    }}
随时随地看视频慕课网APP
我要回答