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.
You can check it easily
if (typeof(T).Name == "List`1")
{
// T is a generic list
}
As mentioned by drf a better way which does not rely on internal implementations is:
if (typeof(T).GetGenericTypeDefinition() == typeof(List<>))
{
// T is a generic list
}