3

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?

Ali EXE
  • 853
  • 1
  • 7
  • 21
  • https://stackoverflow.com/questions/17190204/check-if-object-is-dictionary-or-list – Maytham Fahmi Jul 01 '22 at 04:42
  • @MaythamFahmi, the accepted answer does not take arrays into consideration. That's why I asked for it. There should be a neat way to see if a parameter is made of more than one item. – Ali EXE Jul 01 '22 at 04:49
  • 2
    Why though? It's better to force the caller to be specific, and call different methods for each case. – Jeremy Lakeman Jul 01 '22 at 04:50
  • @JeremyLakeman, that's true. It might be a bad design. But still I want to know if a given parameter is a single object, or anything more than a single one. – Ali EXE Jul 01 '22 at 04:51
  • You could check if the object implements `IEnumerable`. But beware that also `string` does it. – Klaus Gütter Jul 01 '22 at 05:01
  • Let's compare to JS. In JavaScript we only have one collection type, `[]` and we can check the presence of `.length` to check if it's a collection or a single object. @KlausGütter, does that also include arrays? – Ali EXE Jul 01 '22 at 05:10
  • "does that also include arrays" - yes, arrays implement `IEnumerable` otherwise foreach would not work on them. – Klaus Gütter Jul 01 '22 at 05:12
  • Some clarifications would help someone to write code for you: do you consider arrays of *value type* (`int[10]`) as "a collection of objects"? Is `string` "a collection of char" or "single object"? Do you consider type with an indexer, but not derived from of IList/IEnumerable/ICollection as "a collection of object" (due to ability to say `parameter[1]`) or "a single object" (since it is not derived from the interface you like) - I think based on your comment about JavaScript the answer is "single", but it good to write explicitly (`var a={}; a[1]="test"` is valid JavaScript) – Alexei Levenkov Jul 01 '22 at 05:39
  • https://stackoverflow.com/questions/750039/determine-if-object-derives-from-collection-type This question has some pretty well-explanatory and extended answers on this. – Stratis Dermanoutsos Jul 01 '22 at 06:13
  • 2
    Bear in mind that there is nothing stopping anyone from constructing a new type that, logically, represents a collection of objects whilst supporting none of the conventional interfaces that most standard collections implement. There's nothing "inherent" about a collection that is necessarily detectable. It seems strange, therefore, that your code somehow always works correctly for objects but cannot for collections. – Damien_The_Unbeliever Jul 01 '22 at 06:47
  • Why you need this . for what ? Can you show some context for this? – TimChang Jul 02 '22 at 02:07

2 Answers2

3

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.

S. ten Brinke
  • 2,557
  • 4
  • 25
  • 50
0

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.
    }
     
TimChang
  • 2,249
  • 13
  • 25