You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过System.Reflection.Metadata获取接口实现类的接口完全限定名

解决方案

要解析interfaceImplementation.Interface对应的接口完全限定名,需要根据它的句柄类型(当前程序集定义的接口用TypeDefinitionHandle,引用程序集的接口用TypeReferenceHandle)分别处理,以下是具体实现:

核心逻辑步骤

  • 判断interfaceImplementation.Interface的句柄类型:
    • 如果是TypeDefinitionHandle:直接读取当前程序集内的接口定义,获取命名空间和类型名。
    • 如果是TypeReferenceHandle:读取引用类型的元数据,解析其命名空间和类型名。
  • 将命名空间与类型名拼接成[命名空间].[类型名]格式的完全限定名,即可与目标接口名称对比。

修改后的完整代码

namespace ReflectionMetadataTest
{
   using System;
   using System.IO;
   using System.Reflection.Metadata;
   using System.Reflection.PortableExecutable;

   public static class Program
   {
      // 定义要查找的目标接口完全限定名,比如 "System.IDisposable"
      private const string TargetInterfaceFullName = "System.IDisposable";

      static int Main(string[] args)
      {
         if (args.Length < 1)
         {
            Console.Error.WriteLine("Please specify a single file path.");
            return 1;
         }

         string filePath = new FileInfo(args[0]).FullName;

         using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
         {
            using (var peReader = new PEReader(fileStream))
            {
               if (!peReader.HasMetadata)
               {
                  return 2;
               }

               MetadataReader metadataReader = peReader.GetMetadataReader();

               foreach (var typeDefinitionHandle in metadataReader.TypeDefinitions)
               {
                  var typeDefinition = metadataReader.GetTypeDefinition(typeDefinitionHandle);
                  var interfaceHandles = typeDefinition.GetInterfaceImplementations();

                  foreach (var interfaceHandle in interfaceHandles)
                  {
                     var interfaceImplementation = metadataReader.GetInterfaceImplementation(interfaceHandle);
                     var interfaceTypeHandle = interfaceImplementation.Interface;

                     // 解析接口的完全限定名
                     string interfaceFullName = GetFullTypeName(metadataReader, interfaceTypeHandle);

                     // 与目标接口名称对比
                     if (string.Equals(interfaceFullName, TargetInterfaceFullName, StringComparison.Ordinal))
                     {
                        // 获取当前实现类的完全限定名
                        string implementingTypeFullName = GetFullTypeName(metadataReader, typeDefinitionHandle);
                        Console.WriteLine($"找到实现目标接口的类:{implementingTypeFullName}");
                     }
                  }
               }

               return 0;
            }
         }
      }

      // 通用方法:根据类型句柄获取完全限定名
      private static string GetFullTypeName(MetadataReader reader, EntityHandle typeHandle)
      {
         return typeHandle switch
         {
            TypeDefinitionHandle defHandle => 
               $"{reader.GetString(reader.GetTypeDefinition(defHandle).Namespace)}.{reader.GetString(reader.GetTypeDefinition(defHandle).Name)}",
            TypeReferenceHandle refHandle => 
               $"{reader.GetString(reader.GetTypeReference(refHandle).Namespace)}.{reader.GetString(reader.GetTypeReference(refHandle).Name)}",
            // 处理特殊情况:类型规范(比如泛型实例),如需更复杂场景可扩展
            TypeSpecificationHandle specHandle => 
               reader.GetString(reader.GetTypeSpecification(specHandle).TypeSignature.GetSignatureType().GetName(reader)),
            _ => throw new NotSupportedException($"不支持的类型句柄:{typeHandle.Kind}")
         };
      }
   }
}

关键说明

  • GetFullTypeName是通用方法,能处理三种常见的类型句柄,覆盖当前程序集、引用程序集以及泛型接口的情况。
  • 对比时使用StringComparison.Ordinal避免文化差异导致的匹配错误,符合.NET类型名称的匹配规则。
  • 无需加载任何引用程序集,完全通过元数据读取实现判断,满足你的场景需求。

内容的提问来源于stack exchange,提问作者ackh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 23:55:19