How to know a given variable is a collection rather than a simple item in C#?

Viewed 78

Let's say I have this method:

public void DoSomething(object parameter)

Since it accepts object as input, arrays and lists and IEnumerable<T> can be passed to it.

I want to check the type and make sure that it's a single object, not a collection of objects.

I can check each collection possibility separately, but is there a neat better way to check it?

2 Answers

The comments already reference this, but you could check if the item is an ICollection or IEnumerable.

if(parameter is IEnumerable enumerable)
{
 // You can access the non-generic list with enumerable
}

Note that a string also implements this. So if you don't want that specific type, you could add and is not string to the statement. But also keep in mind, you can create your own types that implement IEnumerable and then it would also ne accepted.

I see you reference javascript in the comments. Javascript, AFAIK, only has an array type. C# has multiple "list" types, and a big part of that is IEnumerable, which allows you to enumerate a list of items. It doesn't matter if that is a list, queue, stack, array, etc..

You could also check for ICollection, or something like ICollection<object> or IEnumerable<object>.

I am mostly repeating the answers from the linked answer from the comment: Check if Object is Dictionary or List

It is a bad practice to do this, though. I feel like this is an https://xyproblem.info/ ; it would be better to explain to us WHY you are doing this, perhaps we can solve the problem that is causing you to need this code.

If this answer doesn't help you, please explain why so we can be more specific.

Because :

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
public interface IEnumerable<out T> : IEnumerable

List and Array all implement IList<T> and IList<T> also implement IEnumerable So quikly answer is that only need check IEnumerable:

public void DoSomething(object parameter)
{
    if(parameter is not IEnumerable)
    {
         //here
    }
}

But it's like XY Problem I guess you want this ? but I don't really know what you want.

public void DoSomething<T>(T parameter) where T : XXXClass
    {
         //to make soure parameter is implement XXXClass.
    }
     
Related