c# - 获取引用类型的全名而不加载其程序集

标签 c# reflection

我有一个 .Net 项目,其中有一个程序集 (*.dll),我必须列出所包含的类型及其成员。但是,我没有获得程序集的引用信息。

假设我得到了 A.dll 其中有一个类型:

public class TypeInA : IInterfaceInB
{
    ...
}

由于没有给我 B,所以当我尝试调用时,我收到 FileNotFoundException

typeof(TypeInA).GetInterfaces()

因为它找不到B.dll

我不需要有关 IInterfaceInB 的详细信息,只需要其命名空间限定名称。有没有办法可以在不加载 B.dll 的情况下获得它?

更多上下文

我正在关注 MetadataLoadContext docs加载 A.dll 并枚举其类型:

var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
var paths = new List<string>(runtimeAssemblies) {path};
var resolver = new PathAssemblyResolver(paths);
using var context = new MetadataLoadContext(resolver);

var assembly = context.LoadFromAssemblyPath(path);

最佳答案

Docs 提供你也发帖了

This collection, besides assemblies you want to inspect directly, should also include all needed dependencies. For example, to read the custom attribute located in an external assembly, you should include that assembly or an exception will be thrown.

由于您没有 B.dll,我认为当您尝试访问该程序集中的任何信息时它抛出异常是正常的。

但是,当我在 A.dll 上使用 ildasm.exe 时,我可以轻松看到实现的接口(interface)的名称。所以至少应该可以得到名字。

It is possible!!!

有一个反编译库叫dnlib ,我偶尔使用。这是一个示例代码,您可以在没有 B.dll 的情况下读取 A.dll,并且还可以获取 Types 实现的接口(interface) FullName。

using System;
using System.Linq;
using dnlib.DotNet;
......
......
private static void Main(string[] args) {
    // You need a module context in order to load an assembly
    var moduleContext = ModuleDef.CreateModuleContext();
    // This is the loaded module, please take note that it not loaded into your Domain
    var loadedModule = ModuleDefMD.Load(@"A.dll", moduleContext);
    var classes = loadedModule
        .GetTypes() //You want types in this assembly
         // I think you need classes, (structs too maybe?)
         // But you do not need the Module
        .Where(t=>t.IsClass && t.IsGlobalModuleType == false);

    foreach (var typeDef in classes) {
        Console.WriteLine($"{typeDef.FullName} implements:");
        foreach (var typeDefInterface in typeDef.Interfaces) {
            Console.WriteLine($"  {typeDefInterface.Interface.FullName}");
        }
    }
    Console.ReadKey();
}

关于c# - 获取引用类型的全名而不加载其程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64564983/

相关文章:

c# - 使用 KeyVault secret 覆盖 Azure 应用服务和本地中的应用程序设置

vb.net - 从父类更改子类只读属性

java - Java中如何通过反射访问父类(super class)的父类(super class)的私有(private)字段?

c# - C#Python输入法返回错误

c# - 附加属性绑定(bind)不起作用

visual-studio - 如何基于另一个类生成代码?

c# - 使用反射获取私有(private)属性的私有(private)属性

scala - 如何通过 Scala 反射访问默认参数值?

c# list.OrderBy 根本不工作?

javascript - Ajax POST 数据未出现在模式中