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?
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 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.
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!
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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With