I have a marker interface defined as
public interface IExtender<T>
{
}
I have a class that implements IExtender
public class UserExtender : IExtender<User>
At runtime I recieve the UserExtender type as a parameter to my evaluating method
public Type Evaluate(Type type) // type == typeof(UserExtender)
How do I make my Evaluate method return
typeof(User)
based on the runtime evaluation. I am sure reflection is involved but I can't seem to crack it.
(I was unsure how to word this question. I hope it is clear enough.)
-
There is an example of doing what you describe in the MSDN documentation for the GetGenericTypeDefinition method. It uses the GetGenericArguments method.
Type[] typeArguments = t.GetGenericArguments(); Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length); foreach (Type tParam in typeArguments) { Console.WriteLine("\t\t{0}", tParam); }In your example I think you would want to replace
twiththis. If that doesn't work directly you may need to do something with the GetInterfaces method to enumerate the current interfaces on your type and thenGetGenericArguments()from the interface type.From spoon16 -
I went this way based on some of the tidbits provided. It could be made more robust to handle multiple generic arguments on the interface.... but I didn't need it to ;)
private static Type SafeGetSingleGenericParameter(Type type, Type interfaceType) { if (!interfaceType.IsGenericType || interfaceType.GetGenericArguments().Count() != 1) return type; foreach (Type baseInterface in type.GetInterfaces()) { if (baseInterface.IsGenericType && baseInterface.GetGenericTypeDefinition() == interfaceType.GetGenericTypeDefinition()) { return baseInterface.GetGenericArguments().Single(); } } return type; }From berko -
I read your question completely differently than the other answers.
If the evaluate signature can be changed to:
public Type Evaluate<T>(IExtender<T> it) { return typeof(T); }This doesn't require the calling code to change, but does require the parameter to be of type
IExtender<T>, however you can easily get at the typeT:// ** compiled and tested UserExtender ue = new UserExtender(); Type t = Evaluate(ue);Certainly it's not as generic as something just taking a
Typeparameter, but this is a different take on the problem. Also note that there are Security Considerations for Reflection [msdn]From Robert Paulson
0 comments:
Post a Comment