编辑:
当然我的真实代码看起来并不完全像这样。我试着编写半伪代码,以便更清楚我想做的事情。
看起来它只是把事搞砸了。
所以,我真正想做的是:
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!
}
}
我得到“无法应用运营商”&lt;'到'方法组'和'System.Type'类型的操作数“ 有关如何解决这个问题的任何想法?
答案 0 :(得分:142)
这是一些示例代码。请注意,我将查询表达式更改为点表示法 - 当您基本上只有一个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
}
}
}
原始回答
让我们暂时忽略调用变量“接口”的明显问题。
你必须通过反思来称呼它。泛型的要点是在 compile 时间进行更多类型检查。你不知道编译时的类型是什么 - 因此你必须使用泛型。
获取泛型方法,并在其上调用MakeGenericMethod,然后调用它。
您的界面类型本身是否通用?我问,因为你正在调用MakeGenericType,但没有传入任何类型的参数......你是否试图调用
Method<MyNamespace.Interface<string>>(); // (Or whatever instead of string)
或
Method<MyNamespace.Interface>();
如果是后者,则只需要调用MakeGenericMethod - 而不是MakeGenericType。