Verilen bir değerin genel bir liste olup olmadığını nasıl kontrol ederim?


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

Verilen nesnenin bir liste olup olmadığını veya bir listeye atılıp atılamayacağını kontrol etmenin en iyi yolu nedir?


Belki cevabı burada bulabilirsiniz stackoverflow.com/questions/755200/…
Maksim Kondratyuk

Yanıtlar:


96
using System.Collections;

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

}

4
Bu işe yaramıyor - aşağıdaki istisnayı alıyorum - değer IList 'System.Collections.Generic.IList <T>' genel türünü kullanarak '1' türü bağımsız değişkenler gerektirir

17
System.Collections kullanarak eklemeniz gerekir; kaynak dosyanızın üstünde. Önerdiğim IList arayüzü jenerik sürüm DEĞİL (dolayısıyla ikinci kontrol)
James Couvares

1
Haklısın. Bu bir cazibe gibi çalışıyor. Bunu İzleme penceremde test ediyordum ve eksik ad alanını unuttum. Bu çözümü daha çok beğendim, çok basit

3
Bu çalışmıyor. 4.0 IList <T>! = IList? Her neyse, jenerik ve IEnumerable olup olmadığını kontrol etmem ve ardından kontrol etmek istediğim özelliğin varlığını kontrol etmem gerekiyordu, "Count". Sanırım bu zayıflık kısmen WCF'nin tüm List <T> 'lerinizi T []' ye dönüştürmesinin nedenidir.

1
@Edza Yanlış. Bu genellikle o zamandan beri çalışır List<T>ve ObservableCollection<T>uygulanır IList.
HappyNomad

124

Uzatma yöntemlerini kullanmaktan hoşlananlar için:

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

Yani şunları yapabiliriz:

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

3
.Net Core için bunun biraz değiştirilmesi gerekiyorreturn oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);
Rob L

Tıkır tıkır çalışıyor! Yalnızca türe sahipseniz, nesne yoksa bu sizin için çalışacaktır! Teşekkürler!!
gatsby

IList<>Bunun yerine kontrol etmek daha güvenli olur mu?
nl-x

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

}

GetType () için bir çağrıya ihtiyacınız olduğunu düşünüyorum, örneğin value.GetType (). GetGenericArguments (). Length> 0
ScottS

4

Victor Rodrigues'in cevabına dayanarak, jenerikler için başka bir yöntem geliştirebiliriz. Aslında, orijinal çözüm yalnızca iki satıra indirgenebilir:

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

İşte .NET Standard'da çalışan ve arabirimlere karşı çalışan bir uygulama:

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

Ve işte testler (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

Aşağıdaki kodu kullanıyorum:

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

0

Muhtemelen en iyi yol böyle bir şey yapmaktır:

IList list = value as IList;

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

Bu size maksimum esneklik sağlayacak ve aynı zamanda IListarayüzü uygulayan birçok farklı türle çalışmanıza izin verecektir .


3
bu, istendiği gibi genel bir liste olup olmadığını kontrol etmez .
Lucas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.