I need to use the following generic class and method ParseFrom()
in it:
public sealed class MessageParser<T> : MessageParser where T : IMessage<T>
{
public MessageParser(Func<T> factory); //constructor
public T ParseFrom(byte[] data);
}
Now, I do not know the type of the parameter for this class at compile time, so I use type reflection and MakeGenericType()
method to do that:
//Assuming itemInstance is given as input parameter
Type typeArgument = itemInstance.GetType();
Type genericClass = typeof(MessageParser<>);
var genericType = genericClass.MakeGenericType(typeArgument);
var instance = Activator.CreateInstance(genericType);
It gives me a runtime error: MessageParser<> does not have a parameterless constructor. But when I try to pass Func<T> factory
as a parameter for CreateInstance()
:
var instance = Activator.CreateInstance(genericType, () => Activator.CreateInstance(typeArgument));
it gives me a compile error: Cannot convert lambda expression to type 'string' because it is not a delegate type. Am I using the wrong syntax for a delegate function here?
Expression<Func<object>> create = () => Activator.CreateInstance(typeArgument); var instance = Activator.CreateInstance(genericType, Expression.Lambda(Expression.Convert(create, typeArgument)).Compile());
– MultilateralFunc<T> func = () => (T)Activator.CreateInstance(typeof(T));
whereT
is defined bytypeArgument
.... it's working fine – MultilateralFunc<Message>
... there is second expresion thereExpression.Convert
... which makes right delegate – MultilateralConvert
only ensures that the return type of the delegate is of the right type (by performing the cast in the delegate body, which isn't really preferable when you can construct the original expression to be of the right type, but that's not a dealbreaker, just a missed optimization), not that the delegate itself is of the right type, which is a dealbreaker. – Tonne