2008-09-22 11 views
1

j'ai une interface marqueur définie commeComment puis-je déterminer la valeur d'un paramètre générique sur mon instance de classe

public interface IExtender<T> 
{ 
} 

J'ai une classe qui implémente IExtender

public class UserExtender : IExtender<User> 

Lors de l'exécution je reçois la Type UserExtender en tant que paramètre de ma méthode d'évaluation

public Type Evaluate(Type type) // type == typeof(UserExtender) 

Comment faire ma méthode d'évaluation Renvoyer

typeof(User) 

en fonction de l'évaluation de l'exécution. Je suis sûr que la réflexion est impliquée mais je n'arrive pas à la déchiffrer.

(je ne savais pas comment parole cette question. J'espère qu'il est assez clair.)

Répondre

1

Je suis allé de cette façon en fonction de certaines des informations fournies. Il pourrait être plus robuste pour gérer plusieurs arguments génériques sur l'interface .... mais je ne l'ai pas besoin pour;)

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; 
    } 
1

Il est un exemple de faire ce que vous décrivez dans la documentation MSDN pour la GetGenericTypeDefinition method. Il utilise le 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); 
} 

Dans votre exemple, je pense que vous voulez remplacer t avec this. Si cela ne fonctionne pas directement, vous devrez peut-être faire quelque chose avec le GetInterfaces method pour énumérer les interfaces actuelles sur votre type, puis GetGenericArguments() à partir du type d'interface.

1

Je lis différemment complètement votre question que les autres réponses.

Si l'évaluer la signature peut être modifiée:

public Type Evaluate<T>(IExtender<T> it) 
{ 
    return typeof(T); 
} 

Cela ne nécessite pas le code d'appel au changement, mais ne nécessite le paramètre à être de type IExtender<T>, mais vous pouvez facilement obtenir au type T:

// ** compiled and tested  
UserExtender ue = new UserExtender(); 
Type t = Evaluate(ue); 

Certes, ce n'est pas aussi générique que quelque chose juste prendre un paramètre Type, mais ceci est une opinion différente sur le problème. Notez également qu'il y a Security Considerations for Reflection [msdn]