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
Multiple Webrequest in Same Session
Entity Framework 4.1 Inverseproperty Attribute and Foreignkey
How to Check That a Uri String Is Valid
SQL Injections with Replace Single-Quotation and Validate Integers
What Is The Story of Performance Counters for .Net Core
Show Data in ASP.NET HTML Table
How to Get Device Token in iOS 13 with Xamarin
Openssl.Net Porting a Ruby Example to C# (From Railscasts 143 Paypal-Security)
Method Overloading. Can You Overuse It
Why Does My C# Array Lose Type Sign Information When Cast to Object
Using Ienumerable Without Foreach Loop
Using SQL Convert Function Through Nhibernate Criterion
Decrypt String in C# That Was Encrypted with PHP Openssl_Encrypt
C#/.Net Analysis Tool to Find Race Conditions/Deadlocks
How to Rewrite Complicated Lines of C++ Code (Nested Ternary Operator)