调用泛型方法,只有在执行时已知的类型参数 [英] Calling generic method with a type argument known only at execution time

查看:216
本文介绍了调用泛型方法,只有在执行时已知的类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:

当然我真正的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆