Question Comment déterminer si un type implémente une interface avec une réflexion C #


Est-ce que réflexion dans C# offrir un moyen de déterminer si certains donnés System.Type tapez des modèles d'interface?

public interface IMyInterface {}

public class MyType : IMyInterface {}

// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);

449
2018-02-10 21:49


origine


Réponses:


Vous avez quelques choix sur le dessus de ma tête

  1. typeof(IMyInterface).IsAssignableFrom(typeof(MyType))

  2. typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))


752
2018-02-10 21:53



Utilisation Type.IsAssignableFrom:

typeof(IMyInterface).IsAssignableFrom(typeof(MyType));

47
2018-02-10 21:52



typeof(IMyInterface).IsAssignableFrom(someclass.GetType());

ou

typeof(IMyInterface).IsAssignableFrom(typeof(MyType));

25
2018-02-10 21:53



    public static bool ImplementsInterface( this Type type, Type ifaceType ) {
        Type[] intf = type.GetInterfaces();
        for ( int i = 0; i < intf.Length; i++ ) {
            if ( intf[ i ] == ifaceType ) {
                return true;
            }
        }
        return false;
    }

Je pense que c'est la bonne version, pour trois raisons:

1) Il utilise GetInterfaces et non IsAssignableFrom, il est plus rapide car IsAssignableFrom finit par faire appel à GetInterfaces après plusieurs vérifications.
2) Il itère sur le tableau local, donc il n'y aura pas de contrôle des limites.
3) Il utilise l'opérateur == qui est défini pour Type, donc il est probablement plus sûr que la méthode Equals (que l'appel Contains utilisera éventuellement).


10
2017-10-11 11:37



Modifier la réponse de Jeff pour une performance optimale (grâce au test de performance de Pierre Arnaud):

var type = typeof(MyType);
var implementsInterface = typeof(IMyInterface).IsAssignableFrom(type) && type.IsClass;

Pour trouver tous les types qui implémentent une interface dans un Assembly:

var implementations = typeof(TypeInTargetAssembly).Assembly.GetTypes()
                          .Where(t => typeof(IMyInterface).IsAssignableFrom(t) && t.IsClass);

5
2017-07-07 19:47



Je viens de faire:

public static bool Implements<I>(this Type source) where I : class
{
  return typeof(I).IsAssignableFrom(source);
}

J'aurais aimé pouvoir dire where I : interface, mais interface n'est pas une option de contrainte de paramètre générique. class est aussi proche que possible.

Usage:

if(MyType.Implements<IInitializable>())
  MyCollection.Initialize();

j'ai juste dit Implements parce que c'est plus intuitif. Je reçois toujours IsAssignableFrom flip-flopped.


5
2018-03-31 19:43



Comme quelqu'un d'autre déjà mentionné: Benjamin 10 avril 13 à 22h21 "

Il était facile de ne pas prêter attention et obtenir les arguments pour   IsAssignableFrom en arrière. Je vais aller avec GetInterfaces maintenant: p -

Eh bien, une autre solution consiste simplement à créer une méthode d'extension courte qui répond, dans une certaine mesure, au mode de pensée le plus habituel (et convenu qu'il s'agit d'un choix très personnel pour le rendre un peu plus naturel selon ses préférences ):

public static class TypeHelpers
{
    public static Boolean IsAssignableTo(Type type, Type assignableType)
    {
        return assignableType.IsAssignableFrom(type);
    }
}

public static class TypeExtensions
{
    public static Boolean IsAssignableTo(this Type type, Type assignableType)
    {
        return TypeHelpers.IsAssignableTo(type, assignableType);
    }
}

Et pourquoi ne pas aller un peu plus générique (mais je ne suis pas sûr que ce soit si intéressant, je suppose que je ne fais que passer une autre pincée de sucre "syntaxant"):

public static class TypeHelpers
{
    public static Boolean IsAssignableTo(Type type, Type assignableType)
    {
        return assignableType.IsAssignableFrom(type);
    }

    public static Boolean IsAssignableTo<TAssignable>(Type type)
    {
        return TypeHelpers.IsAssignableTo(type, typeof(TAssignable));
    }
}

public static class TypeExtensions
{
    public static Boolean IsAssignableTo(this Type type, Type assignableType)
    {
        return TypeHelpers.IsAssignableTo(type, assignableType);
    }

    public static Boolean IsAssignableTo<TAssignable>(this Type type)
    {
        return TypeHelpers.IsAssignableTo<TAssignable>(type);
    }
}

Je pense que cela pourrait être beaucoup plus naturel de cette façon, mais encore une fois juste une question d'opinions très personnelles:

var isTrue = michelleType.IsAssignableTo<IMaBelle>();

4
2018-05-04 23:54