ฉันจะตรวจสอบได้อย่างไรว่าค่าที่ระบุเป็นรายการทั่วไป?


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

วิธีใดที่ดีที่สุดในการตรวจสอบว่าวัตถุที่ระบุเป็นรายการหรือสามารถส่งไปยังรายการได้


บางทีคุณอาจพบคำตอบที่นี่stackoverflow.com/questions/755200/…
Maksim Kondratyuk

คำตอบ:


95
using System.Collections;

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

}

4
ไม่ได้ผล - ฉันได้รับข้อยกเว้นต่อไปนี้ - ค่าคือ IList โดยใช้ประเภททั่วไป 'System.Collections.Generic.IList <T>' ต้องการอาร์กิวเมนต์ประเภท '1'

16
คุณต้องเพิ่มโดยใช้ System.Collections; ที่ด้านบนของไฟล์ต้นฉบับของคุณ อินเทอร์เฟซ IList ที่ฉันแนะนำไม่ใช่เวอร์ชันทั่วไป (ดังนั้นการตรวจสอบครั้งที่สอง)
James Couvares

1
คุณถูก. การทำงานนี้เหมือนมีเสน่ห์ ฉันกำลังทดสอบสิ่งนี้ในหน้าต่างนาฬิกาและลืมทุกอย่างเกี่ยวกับเนมสเปซที่หายไป ฉันชอบวิธีนี้ดีกว่าง่ายมาก

3
วิธีนี้ใช้ไม่ได้ ฉันจะเดาใน 4.0 IList <T>! = IList? อย่างไรก็ตามฉันต้องตรวจสอบว่าเป็นแบบทั่วไปหรือไม่และสามารถคำนวณได้จากนั้นตรวจสอบการมีอยู่ของทรัพย์สินที่ฉันต้องการตรวจสอบ "นับ" ฉันคิดว่าจุดอ่อนนี้เป็นสาเหตุหนึ่งที่ทำให้ WCF เปลี่ยน List <T> ทั้งหมดของคุณให้เป็น T []

1
@ เอ็ดซ่าไม่ถูกต้อง. นี้มักจะทำงานตั้งแต่List<T>และการดำเนินการObservableCollection<T> IList
HappyNomad

124

สำหรับพวกคุณที่ชอบใช้วิธีการต่อ:

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

ดังนั้นเราสามารถทำได้:

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

3
สำหรับ. Net Core จำเป็นต้องปรับเปลี่ยนเล็กน้อยถึงreturn oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);
Rob L

ใช้งานได้เหมือนมีเสน่ห์! หากคุณมีเพียงประเภทไม่ใช่วัตถุสิ่งนี้จะเหมาะกับคุณ! ขอบคุณ !!
gatsby

การตรวจสอบIList<>แทนจะปลอดภัยกว่าหรือไม่?
nl-x


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 () เช่น value.GetType () GetGenericArguments () ความยาว> 0
ScottS

4

จากคำตอบของ Victor Rodrigues เราสามารถคิดค้นวิธีอื่นสำหรับยาชื่อสามัญได้ ในความเป็นจริงโซลูชันดั้งเดิมสามารถลดลงเหลือเพียงสองบรรทัด:

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

นี่คือการใช้งานที่ทำงานใน. NET Standard และทำงานกับอินเทอร์เฟซ:

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

และนี่คือการทดสอบ (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

ฉันใช้รหัสต่อไปนี้:

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

0

อาจเป็นวิธีที่ดีที่สุดที่จะทำสิ่งนี้:

IList list = value as IList;

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

สิ่งนี้จะทำให้คุณมีความยืดหยุ่นสูงสุดและยังช่วยให้คุณทำงานกับประเภทต่างๆมากมายที่ใช้IListอินเทอร์เฟซ


3
นี่ไม่ได้ตรวจสอบว่าเป็นรายการทั่วไปตามที่ถามหรือไม่
Lucas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.