Bagaimana cara memeriksa apakah nilai yang diberikan adalah daftar generik?


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

Apa cara terbaik untuk memeriksa apakah objek yang diberikan adalah daftar, atau dapat dimasukkan ke dalam daftar?


Mungkin Anda menemukan jawabannya di sini stackoverflow.com/questions/755200/…
Maksim Kondratyuk

Jawaban:


94
using System.Collections;

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

}

4
Ini tidak berhasil - Saya mendapatkan pengecualian berikut - nilainya adalah IList Menggunakan tipe generik 'System.Collections.Generic.IList <T>' memerlukan argumen jenis '1'

15
Anda perlu menambahkan menggunakan System.Collections; di atas file sumber Anda. Antarmuka IList yang saya sarankan BUKAN versi generik (karenanya pemeriksaan kedua)
James Couvares

1
Kamu benar. Ini bekerja seperti pesona. Saya menguji ini di jendela Watch saya dan lupa semua tentang namespace yang hilang. Saya lebih suka solusi ini, sangat sederhana

3
Ini tidak berhasil. Saya akan menebak dalam 4.0 IList <T>! = IList? Bagaimanapun, saya harus memeriksa apakah itu generik dan IEnumerable, dan kemudian memeriksa keberadaan properti yang ingin saya periksa, "Hitung". Saya kira kelemahan ini adalah sebagian mengapa WCF mengubah semua List Anda <T> menjadi T [].

1
@Eza Salah. Ini biasanya berfungsi sejak List<T>dan ObservableCollection<T>diimplementasikan IList.
HappyNomad

121

Untuk kalian yang menikmati penggunaan metode ekstensi:

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

Jadi, kami dapat melakukan:

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

3
Untuk .Net Core ini perlu dimodifikasi sedikit menjadireturn oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);
Rob L

Bekerja seperti pesona! Jika Anda hanya memiliki tipe bukan objek ini akan bekerja untuk Anda! Terima kasih!!
gatsby

Akankah memeriksa IList<>sebaliknya lebih aman?
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)
{

}

Saya pikir Anda memerlukan panggilan ke GetType () misalnya value.GetType (). GetGenericArguments (). Durasi> 0
ScottS

4

Berdasarkan jawaban Victor Rodrigues, kita dapat menemukan metode lain untuk obat generik. Faktanya, solusi asli dapat direduksi menjadi hanya dua baris:

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

Berikut adalah implementasi yang bekerja di .NET Standard, dan bekerja pada antarmuka:

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

Dan inilah tesnya (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

Saya menggunakan kode berikut:

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

0

Mungkin cara terbaik adalah melakukan sesuatu seperti ini:

IList list = value as IList;

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

Ini akan memberi Anda fleksibilitas maksimum dan juga memungkinkan Anda untuk bekerja dengan berbagai jenis yang mengimplementasikan IListantarmuka.


3
ini tidak memeriksa apakah itu daftar umum seperti yang diminta.
Lucas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.