内部类的公共方法可以从程序集外部访问的一种情况是,该方法实现了接口方法或覆盖了在公共基类中定义的虚方法。
使用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时找到有用的