C #: Calling ForEach on a List <T> generated at runtime

I am generating a List <T> with a parameter of a specific runtime type. I would like to call the ForEach method to iterate over the items in the list:

//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
                            }
                        });

Given the MethodInfo method corresponding to the ForEach method contained in my list type generated at runtime, what is the proper way to call it using an anonymous method? The above is my first hit, but don't know how to declare the type of an anonymous method parameter.

+3
source share
4 answers

You can do it:

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

foreach(var foo in enumerable){
    ...
}

However, I am working to do what you REALLY want.

Edit:

Right, I hope this makes sense.

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 });
}

What does it do:

  • ( , typeof (List < > )
  • , Action
  • (Action)
  • Call ForEach

, Action, , . Action, ...

+4

.

-, . :

Type genericType = typeof(List<>).MakeGenericType(new Type[] { listType });

. , ForEach , Action<T>. , - , , Action<T> , :

methodInfo.Invoke(list, new object[] { x });

x ( Action<T>), , .

0

, , , ForEach ,

class Program
{
    static void Main(string[] args)
    {
        var sampleElement = "Foo";

        Type listType = typeof(List<>).MakeGenericType(sampleElement.GetType());
        Type actionType = typeof(Action<>).MakeGenericType(sampleElement.GetType());

        var list = Activator.CreateInstance(listType);
        var action = Delegate.CreateDelegate(actionType, null, typeof(Program).GetMethod ("ForEach"));

        (list as List<string>).AddRange (new []{ "1", "2" });

        listType.GetMethod ("ForEach").Invoke (list, new object []{ action });
    }

    public static void ForEach(string item)
    {
        Console.WriteLine(item);
    }
}
0

, , .., , .

IList foreach?

0

Source: https://habr.com/ru/post/1710717/


All Articles