Cómo comprobar si una variable es un IEnumerable de algún tipo


Básicamente estoy construyendo una plantilla T4 muy genérica y una de las cosas que necesito que haga es decir print variable.ToString(). Sin embargo, quiero que evalúe las listas y foreach a través de ellas y en su lugar imprimir ListItem.ToString() Mi plantilla T4 no sabe qué tipo variable será antes de tiempo, es por eso que esto es tan genérico.

Pero mi código actual que se genera se ve así:

if(variable!=null)
  if(variable is IEnumerable) //error here
    foreach(var item in variable)
      Write(item.ToString());

Recibo un error del compilador en la línea marcada para "Usando el sistema de tipo genérico.Generico.Colecciones.IEnumerable requiere un argumento de tipo "

En realidad no me importa qué tipo es, solo quiero saber si puedes foreach a través de la variable. ¿Qué código debo usar en su lugar?

Author: Earlz, 2011-01-04

7 answers

Ya ha aceptado una respuesta,sin embargo, ya que genérico IEnumerable<T> implementa el no genérico IEnumerable puede simplemente enviar a eso.

// Does write handle null? Might need some sanity aswell.

var enumerable = variable as System.Collections.IEnumerable; 

if (enumerable != null)
    foreach(var item in enumerable)
         Write(item);
else
    Write(item);     
 49
Author: Courtney D,
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
2011-01-05 00:44:31

Si desea probar para el no genérico IEnumerable entonces necesitarás incluir una directiva using System.Collections en la parte superior de tu archivo fuente.

Si quieres probar un IEnumerable<T> de algún tipo, tendrás algo como esto:

if (variable != null)
{
    if (variable.GetType().GetInterfaces().Any(
            i => i.IsGenericType &&
            i.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
    {
        // foreach...
    }
}
 19
Author: LukeH,
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
2013-11-07 12:31:14

Las otras respuestas han señalado el genérico/IEnumerable no genérico diferencia, pero también debo señalar que también querrá prueba para la Cadena específicamente porque implementa IEnumerable, pero dudo que te quieren tratar como una colección de personajes.

 14
Author: Josh,
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
2011-01-04 03:31:27

En general, sin tipo base/interfaz no genérico, esto requiere GetType y una búsqueda recursiva a través de los tipos base/interfaces.

Sin embargo, eso no se aplica aquí :-) Solo use el {[11] }erableumerable no genérico (System.Collections.IEnumerable), de los cuales genéricoumumerable (System.Collections.Generic.IEnumerable<T>) hereda.

 2
Author: ,
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
2011-01-04 03:27:14

En realidad puede probar la clase base de cualquier tipo genérico directamente.

instance.GetGenericTypeDefinition()  == typeof(IEnumerable<>)
 2
Author: Rob Deary,
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
2015-07-13 21:24:07

Bueno, algo simple pero... si solo tiene:

using System.Collections.Generic;

Es posible que tenga que añadir:

using System.Collections;

El primero define IEnumerable<T> y el segundo define IEnumerable.

 1
Author: Schultz9999,
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
2011-01-04 03:31:57

Esta es una pregunta antigua, pero quería mostrar un método alternativo para determinar si a SomeType es IEnumerable:

var isEnumerable = (typeof(SomeType).Name == "IEnumerable`1");
 -1
Author: ,
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
2015-04-18 13:02:04