Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoking a method of a Generic Class

Here is the Context :

I try to code a mapper for converting my DomainModel Objects to ViewModel Ojects dynamically. The problem I get, it's when I try to invoke a method of generic class by reflection I get this error :

System.InvalidOperationException : Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.

Can someone help-me to figure out where is the fault ? It would be greatly appreciated

Here is the Code (I tried to simplified it) :

public class MapClass<SourceType, DestinationType>
{

    public string Test()
    {
        return test
    }

    public void MapClassReflection(SourceType source, ref DestinationType destination)
    {
        Type sourceType = source.GetType();
        Type destinationType = destination.GetType();

        foreach (PropertyInfo sourceProperty in sourceType.GetProperties())
        {
            string destinationPropertyName = LookupForPropertyInDestinationType(sourceProperty.Name, destinationType);

            if (destinationPropertyName != null)
            {
                PropertyInfo destinationProperty = destinationType.GetProperty(destinationPropertyName);
                if (destinationProperty.PropertyType == sourceProperty.PropertyType)
                {
                    destinationProperty.SetValue(destination, sourceProperty.GetValue(source, null), null);
                }
                else
                {

                       Type d1 = typeof(MapClass<,>);
                        Type[] typeArgs = { destinationProperty.GetType(), sourceType.GetType() };
                        Type constructed = d1.MakeGenericType(typeArgs);

                        object o = Activator.CreateInstance(constructed, null);

                        MethodInfo theMethod = d1.GetMethod("Test");

                        string toto = (string)theMethod.Invoke(o,null);

                }
                }
            }
        }


    private string LookupForPropertyInDestinationType(string sourcePropertyName, Type destinationType)
    {
        foreach (PropertyInfo property in destinationType.GetProperties())
        {
            if (property.Name == sourcePropertyName)
            {
                return sourcePropertyName;
            }
        }
        return null;
    }
}
like image 976
dervlap Avatar asked Oct 01 '10 21:10

dervlap


People also ask

How do you invoke a generic method?

To call a generic method, you need to provide types that will be used during the method invocation. Those types can be passed as an instance of NType objects initialized with particular . NET types.

Can we invoke generic method using .NET reflection?

The first step to dynamically invoking a generic method with reflection is to use reflection to get access to the MethodInfo of the generic method. To do that simply do this: var methodInfo = typeof(ClassWithGenericMethod). GetMethod("MethodName");

How do you declare a generic method How do you invoke a generic method quizlet?

To declare a generic method, you place the generic type <E> immediately after the keyword static in the method. A generic method can be invoked just like a regular method. The compiler automatically discovers the actual type.

Can you give an example of a generic method?

For example, classes like HashSet, ArrayList, HashMap, etc., use generics very well. There are some fundamental differences between the two approaches to generic types.


1 Answers

You need to call GetMethod on the constructed type constructed, not on the type definition d1.

// ...

Type d1 = typeof(MapClass<,>);
Type[] typeArgs = { destinationProperty.GetType(), sourceType.GetType() };
Type constructed = d1.MakeGenericType(typeArgs);

object o = Activator.CreateInstance(constructed, null);

MethodInfo theMethod = constructed.GetMethod("Test");

string toto = (string)theMethod.Invoke(o, null);

// ...
like image 57
LukeH Avatar answered Sep 21 '22 11:09

LukeH