Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if Type or instance implements IEnumerable regardless of Type T

I'm doing a heavy bit of reflection in my current project, and I'm trying to provide a few helper methods just to keep everything tidy.

I'd like to provide a pair of methods to determine if a type or instance implements IEnumerable – regardless of the type T. Here is what I have at the moment:

public static bool IsEnumerable(this Type type) {     return (type is IEnumerable); }  public static bool IsEnumerable(this object obj) {     return (obj as IEnumerable != null); } 

When I test them using

Debug.WriteLine("Type IEnumerable:   " + typeof(IEnumerable).IsEnumerable()); Debug.WriteLine("Type IEnumerable<>: " + typeof(IEnumerable<string>).IsEnumerable()); Debug.WriteLine("Type List:          " + typeof(List<string>).IsEnumerable()); Debug.WriteLine("Type string:        " + typeof(string).IsEnumerable()); Debug.WriteLine("Type DateTime:      " + typeof(DateTime).IsEnumerable()); Debug.WriteLine("Instance List:      " + new List<string>().IsEnumerable()); Debug.WriteLine("Instance string:    " + "".IsEnumerable()); Debug.WriteLine("Instance DateTime:  " + new DateTime().IsEnumerable()); 

I get this as the result:

Type IEnumerable:   False Type IEnumerable<>: False Type List:          False Type string:        False Type DateTime:      False Instance List:      True Instance string:    True Instance DateTime:  False 

The type method doesn't appear to work at all – I had expected a true for the direct System.Collections.IEnumerable match at least.

I'm aware that string is technically enumerable, albeit with a few caveats. Ideally in this case, however, I'd need the helper method to return false for it. I just need the instances with a defined IEnumerable<T> type to return true.

I've probably just missed something fairly obvious – can anyone point me in the right direction?

like image 310
Octopoid Avatar asked Feb 24 '15 17:02

Octopoid


People also ask

What is IEnumerable data type?

IEnumerable is an interface defining a single method GetEnumerator() that returns an IEnumerator interface. It is the base interface for all non-generic collections that can be enumerated. This works for read-only access to a collection that implements that IEnumerable can be used with a foreach statement.

What is IEnumerable and what significance does it hold?

What is IEnumerable in C#? IEnumerable in C# is an interface that defines one method, GetEnumerator which returns an IEnumerator interface. This allows readonly access to a collection then a collection that implements IEnumerable can be used with a for-each statement.

Can you use Linq on IEnumerable?

All LINQ methods are extension methods to the IEnumerable<T> interface. That means that you can call any LINQ method on any object that implements IEnumerable<T> . You can even create your own classes that implement IEnumerable<T> , and those classes will instantly "inherit" all LINQ functionality!


2 Answers

The following line

return (type is IEnumerable); 

is asking "if an instance of Type, type is IEnumerable", which clearly it is not.

You want to do is:

return typeof(IEnumerable).IsAssignableFrom(type); 
like image 185
dav_i Avatar answered Oct 20 '22 08:10

dav_i


In addition to Type.IsAssignableFrom(Type), you can also use Type.GetInterfaces():

public static bool ImplementsInterface(this Type type, Type interfaceType) {     // Deal with the edge case     if ( type == interfaceType)         return true;      bool implemented = type.GetInterfaces().Contains(interfaceType);     return implemented; } 

That way, if you wanted to check multiple interfaces you could easily modify ImplementsInterface to take multiple interfaces.

like image 29
Wai Ha Lee Avatar answered Oct 20 '22 08:10

Wai Ha Lee