在imetadataiport或MonoCecil中,我如何发现内部类中的方法是否可以从其他程序集访问



内部类的公共方法可以从程序集外部访问的一种情况是,该方法实现了接口方法或覆盖了在公共基类中定义的虚方法。

使用imetadataiport,如何发现如果这是一个特定的mdMethodDef的情况?

更新:我也想知道如何在Mono中做到这一点。Cecil,因为这可能会帮助我弄清楚如何在imetadataiport中做到这一点

如果我以这个c#示例为例:

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

这里,Test类成功地实现了ITest接口,正如c#规范(例如13.4.2接口映射)中定义的那样

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

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

…是的……汇编元数据中没有任何东西将Test中的DoSomething方法与ittest中的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中,您需要显式地将类中的方法与接口中的方法关联起来,如果您分析了在VB中的程序集中创建的IL。. NET情况下,您会发现如下:

.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引擎实际上会在运行时对映射进行处理。

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

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

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

可以提供帮助的链接:Mono。比如type。getinterfacemap ?

这里有一点帮助,它不能覆盖你的问题的100%,但它可能会让你足够接近作为或一些额外的工作。

许多宪兵规则必须检查方法(或类型、字段)的可见性,因此创建了一个扩展方法IsVisible来处理大多数所需的检查。通过大多数我的意思是有一件事没有(尚未)实现是支持[InternalVisibleTo]属性。

对于MethodRocks.cs中的方法查找,其他文件包含IsVisible扩展方法TypeDefinition和FieldDefinition以及许多其他扩展方法,您可以在使用Cecil时找到有用的

相关内容

  • 没有找到相关文章

最新更新