How to Check If a Given Value Is a Generic List

How do I check if a given value is a generic list?

using System.Collections;

if(value is IList && value.GetType().IsGenericType) {

}

How to check if T is a list of objects in a generic method

This is not a complete answer, but it's too long for a comment and might help you understand some of the issues better.

// Resharper says: the given expression is never of the provided type
if (typeof(T) is List<object>)

And Resharper is right. The is operator checks whether the instance on the left is of the type on the right, so in your case it checks if typeof(T) is an instance of List<object>. However, typeof(T) returns a Type instance which represents the type of T. The correct way to check (if you are after the exact type) would be

if (typeof(T) == typeof(List<object>))

But note that this will only apply if T is exactly List<object>. If it is also OK to have a subtype of List<object>, the line would be

if (typeof(List<object>).IsAssignableFrom(typeof(T)))

But your problems don't end there. You seem to assume that List<object> is a supertype of all lists. This is not the case, even if we can assume that we will only ever work with the List<T> implementation for lists. The reson for this is that List<T> is invariant.

Invariance means that a list of cats is not a list of mammals. If this seems counterintuitive, that's because you think of a list as a fixed collection that you want to read from. However, you can also add new items to a C# list, and if you were allowed to treat a List<Cat> as a List<Mammal> you could end up trying to add an elephant to that list, and this would cause no end of confusion to anyone else still holding a reference to that list as a List<Cat>.

For a solution to the type checking problem, I think drf's comment to dotctor's answer is the cleanest way to do what you think you want to do:

typeof(T).GetGenericTypeDefinition() == typeof(List<>)

As a final aside, the following code also looks wonky:

var deserialized = Deserialize<List<T>>(file);

You do this after figuring out that T is really a List<Something>, so you're now trying to deserialize your file as a List<List<Something>>, which is probably not what you want.

Check if object is a System.Generic.ListT, for any T

You can use Type.GetGenericTypeDefinition

object obj = GetObject(code);
Type type = obj?.GetType();
bool isList = type != null
&& type.IsGenericType
&& type.GetGenericTypeDefinition() == typeof(List<>);

If object is Generic List

This will return "True"

List<int> myList = new List<int>();

Console.Write(myList.GetType().IsGenericType && myList is IEnumerable);

Do you care to know if it's exactly a "List"... or are you ok with it being IEnumerable, and Generic?

Checking for item in Generic List before using it

Either use Find once and compare the result with default(T), or if default(T) could be the item itself, use FindIndex and check whether the index is -1:

int index = list.FindIndex(x => x...);
if (index != -1)
{
var item = list[index];
// ...
}

If you're using .NET 3.5 or higher, it's more idiomatic to use LINQ - again, if default(T) isn't a problem, you could use something like:

var item = list.FirstOrDefault(x => x....);
if (item != null)
{
...
}

Using LINQ will let you change from List<T> to other collections later on without changing your code.

Generic method, how to get values if it is a List?

You can use a cast to get the IList.

IList list = something as IList;
if( list != null )
{
object temp = list[index.Value];
}

However it might be simpler and more type safe to have a generic method overload dedicated to IList instead of one massive generic method.

public void MyGenericMethod<T>(IList<T> something, int index)
{
var item = something[index];
// etc...
}

Check if var is a List of any kind of objects

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



Related Topics



Leave a reply



Submit