Làm cách nào để kiểm tra xem một giá trị đã cho có phải là một danh sách chung không?


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

Cách tốt nhất để kiểm tra xem đối tượng đã cho có phải là danh sách hay có thể được truyền vào danh sách?


Có thể bạn tìm thấy câu trả lời ở đây stackoverflow.com/questions/755200/…
Maksim Kondratyuk

Câu trả lời:


93
using System.Collections;

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

}

4
Điều này không hoạt động - tôi nhận được ngoại lệ sau - giá trị là IList Sử dụng kiểu chung 'System.Collections.Generic.IList <T>' yêu cầu đối số loại '1'

15
Bạn cần thêm bằng cách sử dụng System.Collections; trên đầu tệp nguồn của bạn. Giao diện IList mà tôi đề xuất KHÔNG phải là phiên bản chung (do đó là lần kiểm tra thứ hai)
James Couvares

1
Bạn đúng. Công việc này như một cái duyên vậy. Tôi đang thử nghiệm điều này trong cửa sổ Xem của mình và quên tất cả về vùng tên bị thiếu. Tôi thích giải pháp này hơn, rất đơn giản

3
Điều này không hoạt động. Tôi đoán trong 4.0 IList <T>! = IList? Dù sao, tôi phải kiểm tra xem nó có phải là chung chung và có thể đếm được hay không, sau đó kiểm tra sự tồn tại của thuộc tính mà tôi muốn kiểm tra, "Count". Tôi cho rằng điểm yếu này một phần là lý do tại sao WCF biến tất cả Danh sách <T> của bạn thành T [].

1
@Edza Không chính xác. Điều này thường hoạt động kể từ List<T>ObservableCollection<T>thực hiện IList.
HappyNomad

121

Đối với những bạn thích sử dụng các phương pháp mở rộng:

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

Vì vậy, chúng tôi có thể làm:

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

3
Đối với Net Lõi này cần phải được sửa đổi một chút đểreturn oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);
Rob L

Hoạt động như một sự quyến rũ! Nếu bạn chỉ có loại không phải đối tượng, điều này sẽ làm việc cho bạn! Cảm ơn!!
gatsby

IList<>Thay vào đó, kiểm tra có an toàn hơn không?
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)
{

}

Tôi nghĩ bạn cần một lệnh gọi tới GetType (), ví dụ: value.GetType (). GetGenericArguments (). Length> 0
ScottS 27/04/09

4

Dựa trên câu trả lời của Victor Rodrigues, chúng ta có thể nghĩ ra một phương pháp khác cho thuốc generic. Trên thực tế, giải pháp ban đầu có thể được rút gọn chỉ còn hai dòng:

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

Đây là một triển khai hoạt động trong .NET Standard và hoạt động dựa trên các giao diện:

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

Và đây là các bài kiểm tra (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

Tôi đang sử dụng mã sau:

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

0

Có lẽ cách tốt nhất là làm điều gì đó như sau:

IList list = value as IList;

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

Điều này sẽ mang lại cho bạn sự linh hoạt tối đa và cũng cho phép bạn làm việc với nhiều kiểu triển khai IListgiao diện khác nhau .


3
điều này không kiểm tra xem nó có phải là một danh sách chung như đã hỏi.
Lucas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.