Come posso verificare se un dato valore è un elenco generico?


Risposte:


93
using System.Collections;

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

}

4
Questo non funziona - Ottengo la seguente eccezione - il valore è IList L'utilizzo del tipo generico 'System.Collections.Generic.IList <T>' richiede argomenti di tipo '1'

15
È necessario aggiungere utilizzando System.Collections; sopra il file sorgente. L'interfaccia IList che ho suggerito NON è la versione generica (da qui il secondo controllo)
James Couvares

1
Hai ragione. Funziona come un fascino. Lo stavo testando nella mia finestra di controllo e ho dimenticato tutto lo spazio dei nomi mancante. Mi piace di più questa soluzione, molto semplice

3
Questo non funziona. Immagino che in 4.0 IList <T>! = IList? Ad ogni modo, ho dovuto controllare se fosse generico e IEnumerable, quindi verificare l'esistenza della proprietà che volevo controllare, "Count". Suppongo che questa debolezza sia in parte il motivo per cui WCF trasforma tutti i tuoi List <T> in T [].

1
@Edza Errato. Questo di solito funziona da allora List<T>e ObservableCollection<T>implementa IList.
HappyNomad

121

Per voi ragazzi a cui piacciono i metodi di estensione:

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

Quindi, potremmo fare:

if(o.IsGenericList())
{
 //...
}

3
Per .Net Core questo deve essere leggermente modificato inreturn oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);
Rob L

Funziona come un fascino! Se hai solo il tipo e non l'oggetto, questo funzionerà per te! Grazie!!
gatsby

Il controllo sarebbe IList<>invece più sicuro?
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)
{

}

Penso che tu abbia bisogno di una chiamata a GetType () ad esempio value.GetType (). GetGenericArguments (). Lunghezza> 0
ScottS

4

Sulla base della risposta di Victor Rodrigues, possiamo escogitare un altro metodo per i generici. Infatti, la soluzione originale può essere ridotta a due sole righe:

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

Ecco un'implementazione che funziona in .NET Standard e funziona con le interfacce:

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

Ed ecco i test (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

Sto usando il codice seguente:

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

0

Probabilmente il modo migliore sarebbe fare qualcosa del genere:

IList list = value as IList;

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

Questo ti darà la massima flessibilità e ti permetterà anche di lavorare con molti tipi diversi che implementano l' IListinterfaccia.


3
questo non controlla se si tratta di un elenco generico come richiesto.
Lucas
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.