2011-09-24 9 views
2

内部クラスのパブリックメソッドがアセンブリの外部からアクセスできる場合の1つは、メソッドがインターフェイスメソッドを実装するか、パブリックベースクラスで定義された仮想メソッドをオーバーライドする場合です。IMetadataImportまたはMonoCecilでは、内部クラスのメソッドに他のアセンブリからアクセスできるかどうかを知るにはどうすればよいですか?

IMetadataImportを使用すると、これが特定のmdMethodDefのケースであるかどうかをどのように調べることができますか?

アップデート:これはMono.Cecilでどのように行うかを知りたいので、IMetaDataImportでその方法を理解するのに役立ちます。

答えて

3

:ここ

public interface ITest 
{ 
    void DoSomething(); 
} 

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

は、Testクラスが正常にC#の仕様で定義されているように、ITestインタフェースを実装し

(たとえば13.4.2 Interface mappingのために)あなたはこの結果を調べると(.NET ReflectorやILDASMなどのツールを使用して)コンパイルされたアセンブリのコードを表示すると、次のようになります。

...はい...ここでは、テストの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で、あなたが明示的にメソッドを関連付ける必要がありますあなたはILは、VB.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.Cecil something like Type.GetInterfaceMap?

+0

あなたの説明とあなたが提供したリンクのコード(Cecilの 'GetOriginalBaseMethod'メソッドに導かれました)は私が必要としていたものです。どうもありがとうございました。 –

1

ここでは、あなたの質問の100%はカバーしていませんが、のように十分に近くなるかもしれません。また、や追加の作業が必要です。 Gendarmeルールの

多くは、方法(またはタイプ、フィールド)が拡張方法、のisVisibleは、必要なチェックの最もに対処するために作成された視認性を確認しなければなりません。そしてによってほとんど私は、(まだ)実装されていない1つのことが[InternalVisibleTo]属性のサポートであることを意味します。方法については

MethodRocks.csに見えるが、他のファイルは、のisVisible延長TypeDefinitionとのFieldDefinitionための方法およびセシルで作業するときに便利見つけることができる他の拡張メソッドの多くが含まれています。私はこのC#サンプル取る場合

+0

私は何かが足りないかもしれないが、このコードは私が求めていた場合に対処していないようですか?たとえば、IsVisibleがMethodRefで 'System.OrdinalComparer.Equals(string、string)'に呼び出されるシナリオを考えてみましょう。このメソッドのDeclaringType(OrdinalComparer)は内部的なので、IsVisibleはfalseを返します。 (StringComparer.Ordinal.Equals( "a"、 "b") 'を実行した場合)、 –

+0

いいえ、それは動作しません*追加作業なし*すべてのインターフェイスにマッチする/公に公開可能な基底クラス。ビルディングブロックとして使用できるGendarmeの他の場所(インターフェイス、ベースクラス、メソッドマッチングなど)にも同様のコードがありますが、そのまま*あなたの質問の100%をカバーしています。 – poupou

関連する問題