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?


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) {

}

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())
{
 //...
}

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<>));

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();
}

5
if(value is IList && value.GetType().GetGenericArguments().Length > 0)
{

}

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

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

1

J'utilise le code suivant:

public bool IsList(Type type) => IsGeneric(type) && (
            (type.GetGenericTypeDefinition() == typeof(List<>))
            || (type.GetGenericTypeDefinition() == typeof(IList<>))
            );

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.


3
cela ne vérifie pas s'il s'agit d'une liste générique comme demandé.
Lucas
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.