调用泛型方法,只有在执行时已知的类型参数 [英] Calling generic method with a type argument known only at execution time
问题描述
编辑:
当然我真正的code看起来不完全一样。我试着写半伪code,使之更加明确whay我想做的事。
Of course my real code doesn't look exactly like this. I tried to write semi-pseudo code to make it more clear of whay I wanted to do.
看起来它只是把事情搞乱来代替。
Looks like it just messed things up instead.
所以,我居然会喜欢做的事是这样的:
So, what I actually would like to do is this:
Method<Interface1>();
Method<Interface2>();
Method<Interface3>();
...
嗯......我想,也许我可以使用反射把它变成一个循环。所以,问题是:如何我怎么做。我的非常的浅反射的知识。所以,code例子将是巨大的。
Well ... I thought that maybe I could turn it into a loop using reflection. So the question is: How how do I do it. I have very shallow knowledge of reflection. So code examples would be great.
场景是这样的:
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!
}
搜索结果
原帖:
你好!
我在一个命名空间中的所有接口尝试循环,并将其作为参数传递给这样的泛型方法:
I'm trying to loop through all interfaces in a namespace and send them as arguments to a generic method like this:
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!
}
}
我得到的错误是类型名称,却发现局部变量名。
如果我尝试
The error I get is "Type name expected, but local variable name found". If I try
...
foreach(var interface in interfaces)
{
Method<interface.MakeGenericType()>(); // Still get compile error here!
}
}
我得到无法适用于运营商'&LT;'键入方法组'和'的System.Type'的操作数
如何解决这个问题的任何想法?
I get "Cannot apply operator '<' to operands of type 'method group' and 'System.Type'" Any idea on how to get around this problem?
推荐答案
编辑:好的,时间很短,但完整的程序。最基本的答案是和以前一样:
Okay, time for a short but complete program. The basic answer is as before:
- 找到打开泛型方法与Type.GetMethod
- 请它使用通用MakeGenericMethod
- 与调用调用它
下面是一些示例code。请注意,我改变了查询前pression为点记号 - 有一个在使用查询前pression当你基本上只是有一个where子句是没有意义的。
Here's some sample code. Note that I changed the query expression to dot notation - there's no point in using a query expression when you've basically just got a where clause.
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
}
}
}
原来的答复
让我们撇开调用变量接口,开始与明显的问题。
Let's leave aside the obvious problems of calling a variable "interface" to start with.
您必须通过反射来调用它。泛型的一点是把更多的类型检查时的编译的时间。你不知道的类型是在编译时什么 - 因此你必须使用泛型
You have to call it by reflection. The point of generics is to put more type checking at compile time. You don't know what the type is at compile-time - therefore you've got to use generics.
获取泛型方法,并呼吁MakeGenericMethod它,然后调用它。
Get the generic method, and call MakeGenericMethod on it, then invoke it.
是您的接口类型本身实际上通用?我问,因为你在它调用MakeGenericType,但不能传递任何类型的参数......你们是不是要叫
Is your interface type itself actually generic? I ask because you're calling MakeGenericType on it, but not passing in any type arguments... Are you trying to call
Method<MyNamespace.Interface<string>>(); // (Or whatever instead of string)
或
Method<MyNamespace.Interface>();
如果是后者,你只需要MakeGenericMethod通话 - 不是MakeGenericType
If it's the latter, you only need a call to MakeGenericMethod - not MakeGenericType.
这篇关于调用泛型方法,只有在执行时已知的类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!