Як перевірити, чи є дане значення загальним списком?


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

Який найкращий спосіб перевірити, чи є даний об’єкт списком, чи його можна передати до списку?


Можливо, ви знайдете тут відповідь stackoverflow.com/questions/755200/…
Максим Кондратюк

Відповіді:


94
using System.Collections;

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

}

4
Це не працює - я отримую такий виняток - значення IList Використання загального типу 'System.Collections.Generic.IList <T>' вимагає аргументів типу '1'

15
Вам потрібно додати за допомогою System.Collections; поверх вихідного файлу. Інтерфейс IList, який я запропонував, НЕ є загальною версією (звідси друга перевірка)
Джеймс Куварес

1
Ти маєш рацію. Це працює як шарм. Я тестував це у своєму вікні Watch і забув все про відсутність простору імен. Мені подобається це рішення більше, дуже просто

3
Це не працює. Я б здогадався в 4.0 IList <T>! = IList? У будь-якому випадку, мені довелося перевірити, чи було це загальним та IEnumerable, а потім перевірити наявність власності, яку я хотів перевірити, "Count". Я вважаю, що ця слабкість частково полягає в тому, чому WCF перетворює всі ваші списки <T> на T [].

1
@Edza Неправильно. Це , як правило , працює з List<T>і ObservableCollection<T>реалізації IList.
HappyNomad

121

Для вас, хлопці, яким подобається використовувати методи розширення:

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<>);
Роб Л

Працює як шарм! Якщо у вас лише тип, а не об’єкт, це буде працювати для вас! Дякую!!
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

Спираючись на відповідь Віктора Родрігеса, ми можемо розробити інший метод дженериків. Насправді оригінальне рішення можна звести лише до двох рядків:

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
це не перевіряє, чи це загальний список за запитом.
Лукас,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.