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?


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

Jawaban:

94
using System.Collections;

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

}
James Couvares
sumber
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())
{
 //...
}
Victor Rodrigues
sumber
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<>));
Eoin Campbell
sumber
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
sumber
5
if(value is IList && value.GetType().GetGenericArguments().Length > 0)
{

}
BFree
sumber
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>);
}
James M
sumber
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)));
    }
Jeff Siemens
sumber
1

Saya menggunakan kode berikut:

public bool IsList(Type type) => IsGeneric(type) && (
            (type.GetGenericTypeDefinition() == typeof(List<>))
            || (type.GetGenericTypeDefinition() == typeof(IList<>))
            );
Yashar Aliabbasi
sumber
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.

Andrew Hare
sumber
3
ini tidak memeriksa apakah itu daftar umum seperti yang diminta.
Lucas