編集:
もちろん、実際のコードはこれとまったく同じではありません。自分が何をしたいのかをより明確にするために、半疑似コードを書いてみました。
むしろ物事を台無しにしてしまったようです。
つまり、私が実際にやりたいことはこれです:
Method<Interface1>();
Method<Interface2>();
Method<Interface3>();
...
まあ...リフレクションを使ってループにできるかもしれないと思ったのですが、問題はどうやってそれをするかです。とてもリフレクションに関する知識が浅い。そのため、コード例があると助かります。
シナリオは次のようになります。
public void Method<T>() where T : class
{}
public void AnotherMethod()
{
Assembly assembly = Assembly.GetExecutingAssembly();
var interfaces = from i in assembly.GetTypes()
where i.Namespace == "MyNamespace.Interface" // only interfaces stored here
select i;
foreach(var i in interfaces)
{
Method<i>(); // Get compile error here!
}
元の投稿:
こんにちは!
名前空間内のすべてのインターフェースをループし、次のように汎用メソッドに引数として送信しようとしています。
public void Method<T>() where T : class
{}
public void AnotherMethod()
{
Assembly assembly = Assembly.GetExecutingAssembly();
var interfaces = from i in assembly.GetTypes()
where i.Namespace == "MyNamespace.Interface" // only interfaces stored here
select i;
foreach(var interface in interfaces)
{
Method<interface>(); // Get compile error here!
}
}
「型名が必要ですが、ローカル変数名が見つかりました」というエラーが表示されます。
...
foreach(var interface in interfaces)
{
Method<interface.MakeGenericType()>(); // Still get compile error here!
}
}
「演算子 '<' をタイプ 'method group' および 'System.Type' のオペランドに適用できません」というメッセージが表示されます。この問題を回避する方法について何かアイデアはありますか?
ベストアンサー1
編集: さて、短いですが完全なプログラムの時間です。基本的な答えは前と同じです:
- Type.GetMethod で「open」ジェネリックメソッドを見つける
- MakeGenericMethodを使用して汎用化します
- Invokeで呼び出す
ここにサンプル コードがあります。クエリ式をドット表記に変更したことに注意してください。基本的に where 句しかない場合は、クエリ式を使用する意味がありません。
using System;
using System.Linq;
using System.Reflection;
namespace Interfaces
{
interface IFoo {}
interface IBar {}
interface IBaz {}
}
public class Test
{
public static void CallMe<T>()
{
Console.WriteLine("typeof(T): {0}", typeof(T));
}
static void Main()
{
MethodInfo method = typeof(Test).GetMethod("CallMe");
var types = typeof(Test).Assembly.GetTypes()
.Where(t => t.Namespace == "Interfaces");
foreach (Type type in types)
{
MethodInfo genericMethod = method.MakeGenericMethod(type);
genericMethod.Invoke(null, null); // No target, no arguments
}
}
}
元の回答
まず、変数を「インターフェース」と呼ぶことの明らかな問題は脇に置いておきましょう。
リフレクションで呼び出す必要があります。ジェネリックのポイントは、より多くの型チェックを行うことです。コンパイルコンパイル時には型が何であるか分からないため、ジェネリックを使用する必要があります。
ジェネリック メソッドを取得し、それに対して MakeGenericMethod を呼び出して、それを呼び出します。
インターフェース型自体はジェネリックですか? MakeGenericType を呼び出していますが、型引数を渡していないので質問します... 呼び出そうとしているのですか?
Method<MyNamespace.Interface<string>>(); // (Or whatever instead of string)
または
Method<MyNamespace.Interface>();
後者の場合、MakeGenericType ではなく MakeGenericMethod を呼び出すだけで済みます。