4

It is strange but the source code

public class Processor<T> where T: class
{
...
    private object WorkWithSubtype(IRequester nextRequester, Type type)
    {
        if (type.GetInterface("IList") != null)
        {
            var originalType = type.GetGenericArguments()[0];
            var list = Activator.CreateInstance(type);

            var method = typeof(Processor<>).GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(originalType);
            var resList = method.Invoke(this, new object[] { nextRequester });
            typeof(List<>).GetMethod("AddRange").MakeGenericMethod(originalType).Invoke(list, new object[] { resList });
            return list;
        }
    }

    private IEnumerable<K> GetObjects<K>(IRequester requester) where K: class
    {
        ...
        //We can call method WorkWithSubtype in this method sometimes
    }
}

And i get "Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.". The exception is throwing at line 'var resList = method.Invoke(this, new object[] { nextRequester });'. Can you help me? Thanks in advance!

Udgin
  • 119
  • 2
  • 9

2 Answers2

5

You have two generic parameters: one is for the Processor class; the other is for the GetObjects method. In making the generic method, you've supplied a type argument for the method's type parameter, but you haven't supplied a type argument for the class's generic parameter.

Depending on the purpose of the processor class, you could try one of the following solutions:

  • build the closed generic type with a type argument
  • use typeof(Processor<T>) rather than using reflection to build the closed generic type
  • remove the type parameter from the class
  • remove the type parameter from the method

I think the second is most likely to be what you're looking for:

var method = typeof(Processor<T>)
    .GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance)
    .MakeGenericMethod(originalType);

Additionally, AddRange is not a generic method; rather, List<> is a generic type, so:

typeof(List<>)
    .MakeGenericType(originalType)
    .GetMethod("AddRange")
    .Invoke(list, new object[] { resList }); 
phoog
  • 42,068
  • 6
  • 79
  • 117
0

You need to use MakeGenericType like so:

var method = typeof(Processor<>).MakeGenericType(typeof(T)).GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(originalType);

similarly when you invoke the AddRange method.

The problem is that List<string>.AddRange is a different method than List<int>.AddRange and MakeGenericType applies the type parameter to the class. Calling MakeGenericMethod is still required for GetObjects since it has a different generic type parameter (K) than the containing class (T).

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122