如何在循环中设置Type类型的泛型变量?

时间:2014-01-16 00:13:01

标签: c# generics

我想通过调用不同类型的泛型方法在这样的循环中做一些类似的过程。

AAABBB都是类。 CreateProcessorMyProcessor类中的通用方法。

new List<Type> {typeof (AAA), typeof (BBB)}.ForEach(x =>
{
    var processor = MyProcessor.CreateProcessor<x>(x.Name);
    processor.process();
});

这不能编译,我收到错误Cannnot resolve symbol x

技术上,如何实现它? (我知道策略模式更好......)

4 个答案:

答案 0 :(得分:8)

需要反思来处理Type类:

    new List<Type> { typeof(AAA), typeof(BBB) }.ForEach(x => {
        var type = typeof(MyClass<>).MakeGenericType(x);
        dynamic processor = Activator.CreateInstance(type, x.Name);
        processor.process();
    });

答案 1 :(得分:7)

  

抱歉,我更新了我的问题。我打算实际上调用泛型方法。

var method = typeof(MyProcessor).GetMethod("CreateProcessor", new Type[] { typeof(string) });
new List<Type> { typeof(AAA), typeof(BBB) }.ForEach(x =>
{
    dynamic processor = method.MakeGenericMethod(x).Invoke(null, new[] { x.Name });
    processor.process();
});

答案 2 :(得分:0)

这是您使用类型信息创建新变量的方法,使用dynamic您可以调用任何您知道存在的所有类型的方法。我建议(假设这些类型是你自己的类)你实现了一个接口基类或者如果可能的话,它会简化你的很多...

new List<Type> { typeof(string), typeof(int) }.ForEach(x =>
{
    dynamic processor = Activator.CreateInstance(x);
    processor.ToString();
    processor.CallAnyMethodHere();
    processor.Process();
});

已编辑的代码 - 添加明确的示例

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

public class mainClass
{
    public static void Main(string[] args)
    {
        new List<Type> { typeof(StringBuilder), typeof(Int64) }.ForEach(x =>
        {
            dynamic instance = Activator.CreateInstance(x);

            DoSomething(instance);
        });

        Console.ReadKey();
    }

    public static void DoSomething(StringBuilder stringBuilder)
    {
        Console.WriteLine("StringBuilder overload");
    }


    public static void DoSomething(Int64 int64)
    {
        Console.WriteLine("Int64 overload");
    }
}

编辑2 - 仅调用通用方法

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Linq;

public class mainClass
{
    public static void Main(string[] args)
    {
        new List<Type> { typeof(StringBuilder), typeof(Int64) }.ForEach(x =>
        {
            var methodInfoArray = typeof(mainClass).GetMethods();
            var methodInfo = methodInfoArray.First(mi => mi.Name == "DoSomething" && mi.IsGenericMethodDefinition);
            var genericMethod = methodInfo.MakeGenericMethod(new Type[] { x });
            var blah = genericMethod.Invoke(null, new object[] { "Hello" }) as MethodInfo;
        });

        Console.ReadKey();
    }

    public static void DoSomething<T>(string variable)
    {
        Console.WriteLine("DoSomething<T> " + typeof(T) + " overload - " + variable);
    }

    public static void DoSomething(string variable)
    {
        Console.WriteLine("DoSomething - " + variable);
    }

}

答案 3 :(得分:0)

您必须使用反射来创建这样的通用对象。 Microsoft的这个页面对您需要做的事情有一个很好的概述:How to: Examine and Instantiate Generic Types with Reflection