web-dev-qa-db-fra.com

Vérification si le type ou l'instance implémente IEnumerable quel que soit le type T

Je réfléchis beaucoup à mon projet actuel et j'essaie de fournir quelques méthodes d'assistance juste pour garder tout en ordre.

Je voudrais fournir une paire de méthodes pour déterminer si un type ou une instance implémente IEnumerable - quel que soit le type T. Voici ce que j'ai en ce moment:

public static bool IsEnumerable(this Type type)
{
    return (type is IEnumerable);
}

public static bool IsEnumerable(this object obj)
{
    return (obj as IEnumerable != null);
}

Quand je les teste en utilisant

Debug.WriteLine("Type IEnumerable:   " + typeof(IEnumerable).IsEnumerable());
Debug.WriteLine("Type IEnumerable<>: " + typeof(IEnumerable<string>).IsEnumerable());
Debug.WriteLine("Type List:          " + typeof(List<string>).IsEnumerable());
Debug.WriteLine("Type string:        " + typeof(string).IsEnumerable());
Debug.WriteLine("Type DateTime:      " + typeof(DateTime).IsEnumerable());
Debug.WriteLine("Instance List:      " + new List<string>().IsEnumerable());
Debug.WriteLine("Instance string:    " + "".IsEnumerable());
Debug.WriteLine("Instance DateTime:  " + new DateTime().IsEnumerable());

J'obtiens ceci comme résultat:

Type IEnumerable:   False
Type IEnumerable<>: False
Type List:          False
Type string:        False
Type DateTime:      False
Instance List:      True
Instance string:    True
Instance DateTime:  False

La méthode type ne semble pas du tout fonctionner - je m'attendais à un true pour la correspondance directe System.Collections.IEnumerable Au moins.

Je sais que string est techniquement énumérable, mais avec quelques mises en garde. Idéalement dans ce cas, cependant, j'aurais besoin de la méthode d'assistance pour renvoyer false. J'ai juste besoin des instances avec un type IEnumerable<T> Défini pour renvoyer true.

J'ai probablement raté quelque chose d'assez évident - quelqu'un peut-il m'orienter dans la bonne direction?

28
Octopoid

La ligne suivante

return (type is IEnumerable);

demande "si une instance de Type, type est IEnumerable", ce qui n'est clairement pas le cas.

Vous voulez faire, c'est:

return typeof(IEnumerable).IsAssignableFrom(type);
45
dav_i

En plus de Type.IsAssignableFrom(Type) , vous pouvez également utiliser Type.GetInterfaces() :

public static bool ImplementsInterface(this Type type, Type interface)
{
    bool implemented = type.GetInterfaces().Contains(interface);
    return implemented;
}

De cette façon, si vous vouliez vérifier plusieurs interfaces, vous pourriez facilement modifier ImplementsInterface pour prendre plusieurs interfaces.

10
Wai Ha Lee