3

I'm developing an application with .NET Framework 4.6.1 and C#.

I want to do this:

var val = actionArguments[key];
if (val is List<T> as class)

I want to check if val is a List of any kind of object but that statement doesn't compile.

How can I check if a variable declared as var is a List?

On my application var is List<Code>. Code is a custom class that I made. And List is System.Generic.Collections.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • 2
    `val is IList`? – haim770 Nov 04 '16 at 11:20
  • Possible duplicate of [Check if Property is List using Reflection in C#](http://stackoverflow.com/questions/38617920/check-if-property-is-list-using-reflection-in-c-sharp) – Peter B Nov 04 '16 at 11:21
  • Check out: [Testing if object is of generic type in C#](http://stackoverflow.com/questions/982487/testing-if-object-is-of-generic-type-in-c-sharp). The accepted answer will do to find out whether it's a `List<>`. Look further down for Jon Skeet's answer, if you want to test for derived classes as well. Things get harder here, and there may be edge cases. As people have suggested, checking the `IList` interface may be the best thing for your particular situation, just understand that's it not exactly the same thing as you asked to do. – Nathan Cooper Nov 04 '16 at 11:31
  • 2
    If the answer is "yes, it is a list", what specifically do you intend to do with that knowledge? Knowing this might indicate the best way to answer your question. – Lasse V. Karlsen Nov 04 '16 at 11:38

4 Answers4

11

Since List<T> is also implementing the non-generic IList interface, you can simply check

if (val is IList)

That's not to say that one can assume that anything that is IList is neccessarily a List<T>. But, in the case of the OP, that is having some indexer returning an object and needs to differ between specific (perhaps known) types, avoiding GetType() and relying on is IList is good enough for this purpose.

See MSDN

haim770
  • 48,394
  • 7
  • 105
  • 133
3

A wordy comparison, but exact one: any List<T> is generic type and have the same generic type definition

if (val.GetType().IsGenericType && 
    val.GetType().GetGenericTypeDefinition() == typeof(List<>)) { 
  ...
}

Comparison with IList is not enough, an exotic counter example:

// generic, does implement IList, does not implement IList<T>
public class CounterExample<T>: IList {
  ...
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • 1
    Better: `val.GetType().IsGenericType && val.GetType().GetGenericTypeDefinition() == typeof(List<>)` You can use the syntax `List<>` for the type definition (one generic argument omitted). Similarly `Dictionary<,,>`, `Func<,,,>` etc. where the number of commas show the number of type parameters (minus one). – Jeppe Stig Nielsen Nov 04 '16 at 11:53
  • @Jeppe Stig Nielsen: thank you for an excelent suggestion, `List<>` just slipped out of my mind; need more coffee. – Dmitry Bychenko Nov 04 '16 at 11:59
1
if(val is IList && val.GetType().IsGenericType &&
    val.GetType().GetGenericTypeDefinition() == typeof(List<>))
{

}

Be aware you should check if val.GetType() is Generic, only val is IList will return true for ArrayList too.

EDIT:

Like Jeppe Stig Nielsen mention in comments, you should add the check val.GetType().GetGenericTypeDefinition() == typeof(List<>) to the if too.

mybirthname
  • 17,949
  • 3
  • 31
  • 55
  • Being aware of that, also be aware that many types other than `List<>`, including [`System.Collections.ObjectModel.Collection<>` and all the generic classes inheriting from it](https://msdn.microsoft.com/en-us/library/ms132397.aspx), will pass your test above. – Jeppe Stig Nielsen Nov 04 '16 at 12:17
  • @JeppeStigNielsen you are totally right, I never thought of that. Thanks for the comment. – mybirthname Nov 04 '16 at 12:24
0

How about:

var val = actionArguments[key];
var codes = val as List<Code>;

if(codes == null)
{
    // val is not of the desired type, so exit, crash, whatever...
    return;
}

// work with your list of codes...
foreach(var code in codes)
{
    Console.WriteLine(code);
}
Oliver
  • 43,366
  • 8
  • 94
  • 151