C#:在运行时生成的List <T>上调用ForEach

Odr*_*ade 3 c# generics

我正在生成带有运行时确定的类型参数的List <T>。我想调用ForEach方法来遍历列表中的项目:

//Get the type of the list elements
Type elementType = GetListElementType(finfo);

Type listType = Type.GetType("System.Collections.Generic.List`1[" 
                              + elementType.FullName + "], mscorlib", true);

//Get the list
var list = getList.Invoke(null, new Object[] { finfo.GetValue(myObject) });

MethodInfo listForEach = listType.GetMethod("ForEach");

//How do I do this?  Specifically, what takes the place of 'x'?
listForEach.Invoke(list, new object[] { delegate ( x element )
                            {
                                //operate on x using reflection
                            }
                        });
Run Code Online (Sandbox Code Playgroud)

给定与运行时生成的列表类型中包含的ForEach方法相对应的MethodInfo,使用匿名方法调用它的正确方法是什么?上面是我的第一个步骤,但是不知道如何声明匿名方法的参数类型。

jon*_*nii 5

你可以这样做:

var someGenericListYouCreated = ...;
var enumerable = someGenericListYouCreated as IEnumerable;

foreach(var foo in enumerable){
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是,我正在努力做您真正想要的事情。

编辑:

是的,我希望这是有道理的

private class Adapter<T>
{
    private readonly Action<object> act;

    public Adapter(Action<object> act){
        this.act = act;
    }

    public void Do(T o)
    {
        act(o);
    }
}

public static void Main(string[] args)
{
    Type elementType = typeof(string);

    var genericType = typeof(List<>).MakeGenericType(elementType);
    var list = Activator.CreateInstance(genericType);

    var addMethod = list.GetType().GetMethod("Add");
    addMethod.Invoke(list, new object[] { "foo" });
    addMethod.Invoke(list, new object[] { "bar" });
    addMethod.Invoke(list, new object[] { "what" });

    Action<object> printDelegate = o => Console.WriteLine(o);

    var adapter = Activator.CreateInstance(typeof(Adapter<>).MakeGenericType(elementType), printDelegate);
    var adapterDo = adapter.GetType().GetMethod("Do");

    var adapterDelegate = Delegate.CreateDelegate(typeof(Action<string>), adapter, adapterDo);

    var foreachMethod = list.GetType().GetMethod("ForEach");

    foreachMethod.Invoke(list, new object[] { adapterDelegate });
}
Run Code Online (Sandbox Code Playgroud)

这是做什么的:

  1. 创建一个通用列表(注意它正在使用typeof(List <>)
  2. 在此列表中添加一些字符串
  3. 创建一个新的委托,在这种情况下是一个动作
  4. 创建适配器类的实例
  5. 在适配器类上创建我们需要的类型的委托(动作)
  6. 呼吁每个人

请注意,如果知道要处理的类型,则不必一定要使用Action。您可以很容易地使用一个动作,它将起作用...