私が持っている質問はこれです:インターフェイスタイプから取得されたメソッドのMethodInfoオブジェクトがあり、このインターフェイスを実装するクラスのTypeオブジェクトもあるが、明示的な実装で前述のメソッドを実装している場合、そのクラスの実装メソッドに対応するMethodInfoオブジェクトを正しく取得するにはどうすればよいですか?
これを行う必要がある理由は、実装メソッドにいくつかの属性を適用でき、リフレクションを通じてこれらを見つける必要があるためですが、これらの属性を見つける必要があるクラスには、実装クラスとタイプのオブジェクト参照しかありません。インターフェイスのオブジェクト(+対応するMethodInfoオブジェクト)。
それで、私が次のプログラムを持っていると仮定しましょう:
using System;
using System.Reflection;
namespace ConsoleApplication8
{
public interface ITest
{
void Test();
}
public class Test : ITest
{
void ITest.Test()
{
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
Type interfaceType = typeof(ITest);
Type classType = typeof(Test);
MethodInfo testMethodViaInterface =
interfaceType.GetMethods()[0];
MethodInfo implementingMethod =
classType.GetMethod(/* ??? */"Test");
Console.Out.WriteLine("interface: " +
testMethodViaInterface.Name);
if (implementingMethod != null)
Console.Out.WriteLine("class: " +
implementingMethod.Name);
else
Console.Out.WriteLine("class: unable to locate");
Console.Out.Write("Press enter to exit...");
Console.In.ReadLine();
}
}
}
これを実行すると、次のようになります。
interface: Test
class: unable to locate
Press enter to exit...
コードの上部には、???を含む.GetMethod呼び出しがあります。コメント。この部分は私が助けを必要としているものです。ここで指定する必要があるもの(そして私は多くのテストを行ったため、別の方法になります)、またはこのコードを置き換える必要があるもののいずれかです。
インターフェイスからメソッドの明示的な実装を使用したため、メソッドの実際の名前は「テスト」だけではありません。クラスタイプのGetMethods()配列の内容全体を次のコードでダンプすると、次のようになります。
foreach (var mi in classType.GetMethods(
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
Console.Out.WriteLine(mi.Name);
}
それから私はこれを手に入れます:
ConsoleApplication8.ITest.Test <-- this is the one I want
ToString
Equals
GetHashCode
GetType
Finalize
MemberwiseClone
明らかに、名前にはインターフェイスのフルネームとその前の名前空間があります。ただし、オーバーロードが原因で、クラス内でそのような実装メソッドをすべて見つけて(つまり、パラメーターによって異なる複数のTestメソッドがあると仮定して)、パラメーターを比較する必要があるように見えます。
もっと簡単な方法はありますか?基本的に、インターフェイスからメソッドのMethodInfoオブジェクトを取得したら、MethodInfoオブジェクトを取得することにより、このメソッドを実装するクラスの正確なメソッドを見つけたいと思います。
ここではループ状態になっていることに注意してください。クラス内のメソッドをループしてインターフェイスから正確なメソッドを見つける必要がある場合は、見つけたタイミングを特定するための適切な方法がある限り、問題ありません。合っている物。
上記のループを次のように変更しようとしました:
foreach (var mi in classType.GetMethods(
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
if (mi.GetBaseDefinition() == testMethodViaInterface)
Console.Out.WriteLine(mi.Name);
}
これは何も出力しなかったので、そのGetBaseDefinitionようなメソッドでは明らかにインターフェイスからMethodInfoオブジェクトを指していません。
ポインタはありますか?