2

Sample code:

    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;    
    }

In code above, GetObject could return any type of object. Inside DoAction, after calling GetObject, I want to be able to tell if the returned obj is any type of System.Collections.Generic.List<T>. I don't care (nor may know) what T is. So DoAction(10) and DoAction(30) should return true, and DoAction(20) would return false.

Moe Sisko
  • 11,665
  • 8
  • 50
  • 80
  • It may work if you do if (yourVar is List) – Arthur Attout May 17 '17 at 08:19
  • @Arthur: this won't work. Perhaps `(obj is IList)` would be enough though. – vgru May 17 '17 at 08:20
  • @Achilles: `System.Object` does not implement `IEnumerable`. – vgru May 17 '17 at 08:20
  • 2
    Not the focus of your question, but I would advise changing your chained if statement into a switch statement. Secondly, again more a tip than an actual solution : if you return an object, you should be able to work with the returned value as if it were an object. Casting up is _usually_ sign of bad design; although it does happen (e.g. when retrieving a bound item from a control, since any object can be cast into it). However, I see little use for returning an object that could be an ienumerable or a single object. – Flater May 17 '17 at 08:20
  • I agree with @Flater, you are doing something wrong (from the OOP point of view). I believe you are a victim of the [XY problem](https://meta.stackexchange.com/a/66378/130298), and perhaps you could ask a different question stating what is exactly that you're trying to do. – vgru May 17 '17 at 08:23
  • thanks all. Yes,there is some (slightly dodgy) existing code for which i need to maintain backward compatibility. Doing this check makes things safer in my case. – Moe Sisko May 17 '17 at 08:26

2 Answers2

11

You can use Type.GetGenericTypeDefinition

object obj = GetObject(code);
Type type = obj?.GetType();
bool isList = type != null 
           && type.IsGenericType 
           && type.GetGenericTypeDefinition() == typeof(List<>);
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
2

This should work

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

    return obj is IList;
}

Then:

var first = DoAction(10);   //true
var second = DoAction(20);  //false
var third = DoAction(30);   //true
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116