J'ai un type et une interface et j'ai besoin de vérifier que le type implémente l'interface abstraite.
J'ai défini pour écrire un code de force brute à l'aide de la réflexion et c'est assez moche. P>
Je me demande s'il y a une meilleure façon que la mise en œuvre de la force brute que je fais maintenant. P>
Toute idée? P>
Merci. P>
Edit < / strong> p> n'a pas encore vérifié la mise en œuvre, mais le code brut de la force brute ressemble à ceci: p> sans la compilation, je vois déjà un problème Avec des propriétés, que le code doit vérifier si l'interface définit Getter et / ou Setter et vérifie la (les) méthode (s) de droite) au lieu d'assumer aveuglément le getter. Quoi qu'il en soit, comme on peut le voir, le code est assez terne. Je me demande s'il y a une meilleure façon ... p>
4 Réponses :
Vous pouvez déterminer si un type implémente une interface particulière en utilisant Type.ISAssignABLABLEFROM :
public static bool IsAbstractOf<TInterface>(this Type type) { var map = type.GetInterfaceMap(typeof(TInterface)); foreach (var info in map.TargetMethods) { if (!info.IsAbstract) { return false; } } return true; }
On sait que le type implémente l'interface. Ce dont j'ai besoin, c'est si la mise en œuvre est tout abstraite.
@Mark Il n'y a aucun moyen de savoir sans réfléchir chaque membre à voir s'il est abstrait.
Je soupçonne ça. Mais peut-être qu'il y a des astuces liées à la réflexion que je ne suis pas au courant.
Merci, l'utilisation de l'intefacap est l'astuce que je cherchais.
La réponse de Rex M est correcte en général, mais si votre type est un paramètre de type, vous pouvez également faire:
class Foo<T> where T : IWhatever { // Do your thing, secure in the knowledge that T implements IWhatever }
On sait que le type implémente l'interface. Ce dont j'ai besoin, c'est si la mise en œuvre est tout abstraite.
public static bool IsAbstractInterfaceImplementation(Type someType, Type someInterface) { return someType.IsAbstract && someInterface.IsAssignableFrom(someType); }
Cela ne détermine que si la classe est abstraite, non si certaines méthodes sont abstraites.
Vous ne pouvez pas utiliser les noms des membres. Parce qu'il n'y a aucune raison d'assumer, que le nom d'un membre vous indique quoi que ce soit sur l'interface membre de l'interface. La réflexion vous fournit des moyens de voir quelle méthode implémente l'une de l'interface, cependant.
Voici un extrait qui retournerait toute la méthode sur un type donné qui ne sont implémentés que de manière abstraite. P>
static IEnumerable<MethodInfo> GetAbstractImplementations(this Type implementingType, Type interfaceType) { if(!interfaceType.IsInterface) throw new ArgumentException(interfaceType.FullName + " is not an interface."); if(implementingType.IsInterface) throw new ArgumentException(interfaceType.FullName + " is an interface."); if(!interfaceType.IsAssignableFrom(implementingType)) throw new ArgumentException(implementingType.FullName + " does not implement " + interfaceType.FullName + "."); var mapping = implementingType.GetInterfaceMap(interfaceType); return from m in mapping.TargetMethods where m.IsAbstract select m; } public static bool IsAbstractInterfaceImplementationOf(this Type implementingType, Type interfaceType) { return implementingType.GetAbstractImplementations(interfaceType).Any(); }
"Code de force brute utilisant la réflexion" - pouvez-vous le poster?
Que voulez-vous dire exactement lorsque vous dites que le "type implémente l'interface abstraite"?
OK, quelques minutes pour vous assurer que cela fonctionne du tout.
Par "abstraitement", je veux dire que chaque membre d'interface est implémenté à l'aide du mot clé abstrait.
Vous vous demandez simplement, mais pourquoi auriez-vous jamais besoin de vérifier si une classe implémente tous les membres de l'interface avec le mot clé abstrait?
Mes pensées exactement. Vous n'allez jamais rencontrer une instance d'une telle classe, car c'est une classe abstraite par définition.
Outre d'autres choses, votre approche de force brute est généralement fausse, car une méthode de classe publique mettant en œuvre une interface n'a pas besoin d'avoir le même nom. Pensez à VB:
Public Mustoverride Sub FOO () implémente ibar.bar code>.
À moins que je ne manque rien, cela ne fonctionnera pas du tout parce que vous ne vérifiez que le nom au lieu de la signature de la méthode complète.