Determinar si la colección es de tipo IEnumerable


Cómo determinar si el objeto es de tipo IEnumerable ?

Código:

namespace NS {
    class Program {
        static IEnumerable<int> GetInts() {
            yield return 1;
        }
        static void Main() {
            var i = GetInts();
            var type = i.GetType();
            Console.WriteLine(type.ToString());
        }
    }
}

Salida:

NS.1.Program+<GetInts>d__0

Si cambio GetInts para devolver IList, todo está bien la salida es:

 System.Collections.Generic.List`1[System.Int32]

Y esto devuelve false:

namespace NS {
    class Program {
        static IEnumerable<int> GetInts() {
            yield return 1;
        }
        static void Main() {
            var i = GetInts();
            var type = i.GetType();
            Console.WriteLine(type.Equals(typeof(IEnumerable<int>)));
        }
    }
}
Author: Piotr Justyna, 2009-12-04

7 answers

Si te refieres a la colección , entonces solo as:

var asEnumerable = i as IEnumerable<int>;
if(asEnumerable != null) { ... }

Sin embargo, estoy asumiendo (por el ejemplo) que tienes un Type:

El object nunca será "de tipo" IEnumerable<int> - pero podría implementar, me sería de esperar que:

if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...}

Lo haría. Si no sabes el T (int en el anterior), a continuación, compruebe todas las interfaces implementadas:

static Type GetEnumerableType(Type type) {
    foreach (Type intType in type.GetInterfaces()) {
        if (intType.IsGenericType
            && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
            return intType.GetGenericArguments()[0];
        }
    }
    return null;
}

Y llamar:

Type t = GetEnumerableType(type);

Si esto es nulo, no es IEnumerable<T> para cualquier T - de lo contrario, compruebe t.

 99
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-04 13:18:55

La misma técnica que la respuesta de Marc, pero Linqier:

namespace NS
{
    class Program
    {
        static IEnumerable<int> GetInts()
        {
            yield return 1;
        }

        static void Main()
        {
            var i = GetInts();
            var type = i.GetType();
            var isEnumerableOfT = type.GetInterfaces()
                .Any(ti => ti.IsGenericType
                     && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>));
            Console.WriteLine(isEnumerableOfT);
        }
    }
}
 13
Author: Mark Rendle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-04 13:27:20

Desde IEnumerable heredar IEnumerable (no genérica) y si usted no necesita saber cuando un tipo es la IEnumerable y no IEnumerable, a continuación, puede utilizar:

if (typeof(IEnumerable).IsAssignableFrom(srcType))
 13
Author: Serge Intern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 15:10:36

Cómo determinar si el objeto es de tipo IEnumerable ?

Por favor, siéntase libre de usar este método de extensión fino, ultra pequeño y genérico para determinar si algún objeto implementa una interfazumumerable. Extiende el tipo Object, por lo que puede ejecutarlo utilizando cualquier instancia de cualquier objeto que esté utilizando.

public static class CollectionTestClass
{
    public static Boolean IsEnumerable<T>(this Object testedObject)
    {
        return (testedObject is IEnumerable<T>);
    }
}
 7
Author: Piotr Justyna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-20 15:24:12

i es de tipo NS.1.Program+<GetInts>d__0, que es un subtipo de IEnumerable<int>. Por lo tanto, puede utilizar cualquiera

if (i is IEnumerable<int>) { ... }

O IsAssignableFrom (como en la respuesta de Marc).

 3
Author: Heinzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-04 12:35:19

Puedes usar la palabra clave is.

[TestFixture]
class Program
{
    static IEnumerable<int> GetInts()
    {
        yield return 1;
    }

    [Test]
    static void Maasd()
    {
        var i = GetInts();
        Assert.IsTrue(i is IEnumerable<int>);
    }
}
 1
Author: tster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-04 12:37:32
 0
Author: SwDevMan81,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:16