.net - 在 IMetadataImport 或 MonoCecil 中,如何确定内部类中的方法是否可以从其他程序集访问?

标签 .net reflection clr mono.cecil imetadataimport

可以从程序集外部访问内部类的公共(public)方法的情况之一是该方法实现接口(interface)方法或重写公共(public)基类中定义的虚拟方法。

使用 IMetadataImport,如何查明特定 mdMethodDef 是否属于这种情况?

更新:我还想知道如何在 Mono.Cecil 中执行此操作,因为这可能会帮助我弄清楚如何在 IMetaDataImport 中执行此操作。

最佳答案

如果我采用此 C# 示例:

public interface ITest
{
    void DoSomething();
}

public class Test : ITest
{
    public void DoSomething()
    {
    }
}

这里,Test 类成功实现了 C# 规范中定义的 ITest 接口(interface)(例如 13.4.2 Interface mapping )

如果您在已编译的程序集中检查此代码的结果(使用 .NET Reflector 或 ILDASM 等工具),您将看到以下内容:

.method public hidebysig newslot virtual final instance void DoSomething() cil managed
{
    .maxstack 8
    L_0000: nop 
    L_0001: ret 
}

而且...是的...程序集元数据中没有任何内容可以将 Test 中的 DoSomething 方法与 ITest 中的 DoSomething 方法相关联。

在 VB.NET 中,情况有所不同,您需要添加 Implements 关键字以确保其编译:

Public Interface ITest

    Sub DoSomething()

End Interface


Public Class Test
    Implements ITest


    Public Sub DoSomething() Implements ITest.DoSomething

    End Sub
End Class

如您所见,使用 VB.NET,您需要将类中的方法与接口(interface)中的方法显式关联,并且如果您分析在 VB.NET 情况下的程序集中创建了哪些 IL,您就会发现会发现这个:

.method public newslot virtual final instance void DoSomething() cil managed
{
    .override TestVB.ITest::DoSomething
    .maxstack 8
    L_0000: nop 
    L_0001: nop 
    L_0002: ret 
}

因此,对于 VB 编译的程序集,信息就在那里,而对于 C# 编译的程序集,则不存在。这取决于语言。 CLR 引擎实际上会在运行时进行映射。

如果您可以在进程中注入(inject)程序集,此代码可以帮助您确定接口(interface)映射:

    InterfaceMapping im = typeof(Test).GetInterfaceMap(typeof(ITest));

但是,如果您需要仅查看元数据来确定这一点,则必须自己编写该代码。这并不容易,尤其是对于泛型而言。另外不要忘记在 C# 中,公共(public)方法可以隐式实现多个接口(interface)。

可以提供帮助的链接:Mono.Cecil something like Type.GetInterfaceMap?

关于.net - 在 IMetadataImport 或 MonoCecil 中,如何确定内部类中的方法是否可以从其他程序集访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7538689/

相关文章:

c# - 原生 GetUninitializedObject 实际上存在于何处?

.net - IWindsorContainer 不包含 'GetService' 的定义

c# - 如何将字符转换为等效的 System.Windows.Input.Key 枚举值?

c# - 喜欢详细的 Linq 表达式?

java - 调试期间调用 MethodHandle

Android Studio 上的 Java Reflect 无法找到要调用的公共(public)静态方法

.net - .net core 源码中如何维护局部变量使用信息

.net - 防止浏览器在刷新时显示查询重新提交对话框

c# - MVVM轻消息-多个ViewModel实例

c# - 给定一个 C# 类型,获取它的基类和实现的接口(interface)