Проверьте, является ли объект System.Generic.List‹T› для любого T [дубликата]

Образец кода:

    using System.Collections.Generic;
    ...

        // could return anything. 
        private object GetObject(int code)
        {
            object obj = null;

            if (code == 10)
            {
                var list1  = new List<Tuple<int, string>>();
                list1.Add(new Tuple<int, string>(2, "blah"));
                obj = list1;                
            }
            else if (code == 20)
            {
                obj = "hello";
            }
            else if (code == 30)
            {
                var list2 = new List<string>();
                list2.Add("o");
                obj = list2; 
            }
            // else etc, etc. 

            return obj; 
    }

    private bool DoAction(int code)
    {
        object obj = GetObject(code);

        bool isListT = ??? 
        return isListT;    
    }

В приведенном выше коде GetObject может возвращать объект любого типа. Внутри DoAction, после вызова GetObject, я хочу иметь возможность определить, является ли возвращаемый объект каким-либо типом System.Collections.Generic.List<T>. Мне все равно (и я не знаю), что такое T. Таким образом, DoAction(10) и DoAction(30) должны возвращать true, а DoAction(20) возвращать false.


person Moe Sisko    schedule 17.05.2017    source источник
comment
Это может сработать, если вы это сделаете, если (yourVar - List‹Object›)   -  person Arthur Attout    schedule 17.05.2017
comment
@ Артур: это не сработает. Хотя, возможно, (obj is IList) будет достаточно.   -  person Groo    schedule 17.05.2017
comment
@Achilles: System.Object не реализует IEnumerable.   -  person Groo    schedule 17.05.2017
comment
Не в центре вашего вопроса, но я бы посоветовал изменить ваш цепочный оператор if на оператор switch. Во-вторых, опять же больше совет, чем фактическое решение: если вы возвращаете объект, вы должны иметь возможность работать с возвращаемым значением, как если бы это был объект. Заброс обычно является признаком плохого дизайна; хотя это действительно происходит (например, при извлечении связанного элемента из элемента управления, поскольку в него можно привести любой объект). Однако я не вижу особого смысла возвращать объект, который может быть перечисляемым или одиночным объектом.   -  person Flater    schedule 17.05.2017
comment
Я согласен с @Flater, вы делаете что-то не так (с точки зрения ООП). Я считаю, что вы стали жертвой проблемы XY, и, возможно, вы могли бы задать другой вопрос, указав, что именно это ты пытаешься сделать.   -  person Groo    schedule 17.05.2017
comment
Спасибо всем. Да, есть некоторый (слегка хитрый) существующий код, для которого мне нужно поддерживать обратную совместимость. Выполнение этой проверки делает вещи более безопасными в моем случае.   -  person Moe Sisko    schedule 17.05.2017


Ответы (2)


Вы можете использовать Type.GetGenericTypeDefinition

object obj = GetObject(code);
bool isList = obj?.GetType().GetGenericTypeDefinition() == typeof(List<>);
person Tim Schmelter    schedule 17.05.2017
comment
Благодарю. В С# 4.5 я остановился на: obj != null && obj.GetType().IsGenericType && obj.GetType().GetGenericTypeDefinition() == typeof(List‹›) - person Moe Sisko; 18.05.2017

Это должно работать

private static bool DoAction(int code)
{
    object obj = GetObject(code);

    return obj is IList;
}

Потом:

var first = DoAction(10);   //true
var second = DoAction(20);  //false
var third = DoAction(30);   //true
person Hossein Narimani Rad    schedule 17.05.2017