Comment vérifier si une valeur donnée est une liste générique?

89
public bool IsList(object value)
    {
        Type type = value.GetType();
        // Check if type is a generic list of any type
    }

Quelle est la meilleure façon de vérifier si l'objet donné est une liste ou peut être converti en liste?


la source
Peut-être que vous trouvez la réponse ici stackoverflow.com/questions/755200/…
Maksim Kondratyuk

Réponses:

93
using System.Collections;

if(value is IList && value.GetType().IsGenericType) {

}
James Couvares
la source
4
Cela ne fonctionne pas - j'obtiens l'exception suivante - la valeur est IList L'utilisation du type générique 'System.Collections.Generic.IList <T>' nécessite des arguments de type '1'
15
Vous devez ajouter en utilisant System.Collections; en plus de votre fichier source. L'interface IList que j'ai suggérée n'est PAS la version générique (d'où la deuxième vérification)
James Couvares
1
Tu as raison. Cela fonctionne comme un charme. Je testais cela dans ma fenêtre de surveillance et j'ai tout oublié de l'espace de noms manquant. J'aime mieux cette solution, très simple
3
Cela ne marche pas. Je suppose que dans 4.0 IList <T>! = IList? Quoi qu'il en soit, j'ai dû vérifier si c'était générique et IEnumerable, puis vérifier l'existence de la propriété que je voulais vérifier, "Count". Je suppose que cette faiblesse est en partie pourquoi WCF transforme tous vos List <T> en T [].
1
@Edza Incorrect. Cela fonctionne généralement depuis List<T>et est ObservableCollection<T>mis en œuvre IList.
HappyNomad
121

Pour vous les gars qui appréciez l'utilisation des méthodes d'extension:

public static bool IsGenericList(this object o)
{
    var oType = o.GetType();
    return (oType.IsGenericType && (oType.GetGenericTypeDefinition() == typeof(List<>)));
}

Donc, nous pourrions faire:

if(o.IsGenericList())
{
 //...
}
Victor Rodrigues
la source
3
Pour .Net Core, cela doit être légèrement modifié enreturn oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);
Rob L
Fonctionne comme un charme! Si vous n'avez que le type et non l'objet, cela fonctionnera pour vous! Merci!!
gatsby le
La vérification IList<>serait-elle plus sûre?
nl-x
14
 bool isList = o.GetType().IsGenericType 
                && o.GetType().GetGenericTypeDefinition() == typeof(IList<>));
Eoin Campbell
la source
6
public bool IsList(object value) {
    return value is IList 
        || IsGenericList(value);
}

public bool IsGenericList(object value) {
    var type = value.GetType();
    return type.IsGenericType
        && typeof(List<>) == type.GetGenericTypeDefinition();
}
Atif Aziz
la source
5
if(value is IList && value.GetType().GetGenericArguments().Length > 0)
{

}
BGratuit
la source
Je pense que vous avez besoin d'un appel à GetType (), par exemple value.GetType (). GetGenericArguments (). Length> 0
ScottS
4

Sur la base de la réponse de Victor Rodrigues, nous pouvons concevoir une autre méthode pour les génériques. En fait, la solution originale peut être réduite à seulement deux lignes:

public static bool IsGenericList(this object Value)
{
    var t = Value.GetType();
    return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<>);
}

public static bool IsGenericList<T>(this object Value)
{
    var t = Value.GetType();
    return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<T>);
}
James M
la source
3

Voici une implémentation qui fonctionne dans .NET Standard et fonctionne avec les interfaces:

    public static bool ImplementsGenericInterface(this Type type, Type interfaceType)
    {
        return type
            .GetTypeInfo()
            .ImplementedInterfaces
            .Any(x => x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == interfaceType);
    }

Et voici les tests (xunit):

    [Fact]
    public void ImplementsGenericInterface_List_IsValidInterfaceTypes()
    {
        var list = new List<string>();
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IList<>)));
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IEnumerable<>)));
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IReadOnlyList<>)));
    }

    [Fact]
    public void ImplementsGenericInterface_List_IsNotInvalidInterfaceTypes()
    {
        var list = new List<string>();
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(string)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(IDictionary<,>)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(IComparable<>)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(DateTime)));
    }
Jeff Siemens
la source
1

J'utilise le code suivant:

public bool IsList(Type type) => IsGeneric(type) && (
            (type.GetGenericTypeDefinition() == typeof(List<>))
            || (type.GetGenericTypeDefinition() == typeof(IList<>))
            );
Yashar Aliabbasi
la source
0

La meilleure façon serait probablement de faire quelque chose comme ceci:

IList list = value as IList;

if (list != null)
{
    // use list in here
}

Cela vous donnera une flexibilité maximale et vous permettra également de travailler avec de nombreux types différents qui implémentent l' IListinterface.

Andrew Hare
la source
3
cela ne vérifie pas s'il s'agit d'une liste générique comme demandé.
Lucas