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;
}
}
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.
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");
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.
For example, classes like HashSet, ArrayList, HashMap, etc., use generics very well. There are some fundamental differences between the two approaches to generic types.
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);
// ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With