Wie überprüfe ich, ob ein bestimmter Wert eine generische Liste ist?

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

Wie kann am besten überprüft werden, ob das angegebene Objekt eine Liste ist oder in eine Liste umgewandelt werden kann?


quelle
Vielleicht finden Sie hier eine Antwort stackoverflow.com/questions/755200/…
Maksim Kondratyuk

Antworten:

91
using System.Collections;

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

}
James Couvares
quelle
4
Dies funktioniert nicht - ich erhalte die folgende Ausnahme - Wert ist IList Die Verwendung des generischen Typs 'System.Collections.Generic.IList <T>' erfordert Argumente vom Typ '1'
15
Sie müssen mit System.Collections hinzufügen. über Ihrer Quelldatei. Die von mir vorgeschlagene IList-Schnittstelle ist NICHT die generische Version (daher die zweite Überprüfung)
James Couvares
1
Du hast recht. Das funktioniert wie ein Zauber. Ich habe dies in meinem Überwachungsfenster getestet und den fehlenden Namespace vergessen. Ich mag diese Lösung besser, sehr einfach
3
Das funktioniert nicht. Ich würde in 4.0 IList <T> raten! = IList? Wie auch immer, ich musste überprüfen, ob es generisch und IEnumerable war, und dann prüfen, ob die Eigenschaft "Count" vorhanden war, die ich überprüfen wollte. Ich nehme an, diese Schwäche ist teilweise der Grund, warum WCF alle Ihre List <T> in T [] umwandelt.
1
@ Edza Falsch. Dies funktioniert normalerweise seit List<T>und ObservableCollection<T>implementieren IList.
HappyNomad
119

Für euch, die gerne Erweiterungsmethoden verwenden:

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

Also könnten wir tun:

if(o.IsGenericList())
{
 //...
}
Victor Rodrigues
quelle
3
Für .Net Core muss dies leicht geändert werden aufreturn oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);
Rob L
Klappt wunderbar! Wenn Sie nur den Typ und nicht das Objekt haben, funktioniert dies für Sie! Vielen Dank!!
Gatsby
Wäre IList<>es sicherer , nach stattdessen zu suchen?
nl-x
14
 bool isList = o.GetType().IsGenericType 
                && o.GetType().GetGenericTypeDefinition() == typeof(IList<>));
Eoin Campbell
quelle
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
quelle
5
if(value is IList && value.GetType().GetGenericArguments().Length > 0)
{

}
BKostenlos
quelle
Ich denke, Sie brauchen einen Aufruf von GetType (), z. B. value.GetType (). GetGenericArguments (). Länge> 0
ScottS
4

Basierend auf der Antwort von Victor Rodrigues können wir eine andere Methode für Generika entwickeln. Tatsächlich kann die ursprüngliche Lösung auf nur zwei Zeilen reduziert werden:

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.
quelle
3

Hier ist eine Implementierung, die in .NET Standard funktioniert und gegen Schnittstellen funktioniert:

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

Und hier sind die 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
quelle
1

Ich verwende den folgenden Code:

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

Wahrscheinlich wäre der beste Weg, so etwas zu tun:

IList list = value as IList;

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

Dies gibt Ihnen maximale Flexibilität und ermöglicht es Ihnen, mit vielen verschiedenen Typen zu arbeiten, die die IListSchnittstelle implementieren .

Andrew Hare
quelle
3
Dies prüft nicht, ob es sich um eine generische Liste handelt.
Lucas