¿Cómo detecto que un objeto es una colección genérica y qué tipos contiene?

Tengo una utilidad de serialización de cadenas que toma una variable de (casi) cualquier tipo y la convierte en una cadena. Así, por ejemplo, según mi convención, un valor entero de 123 se serializaría como "i: 3: 123" (i = entero; 3 = longitud de la cadena; 123 = valor).

La utilidad maneja todos los tipos primitivos, así como algunas colecciones no genéricas, como ArrayLists y Hashtables. La interfaz tiene la forma

public static string StringSerialize(object o) {}

e internamente detecto de qué tipo es el objeto y lo serializo en consecuencia.

Ahora quiero actualizar mi utilidad para manejar colecciones genéricas. Lo curioso es que no puedo encontrar una función adecuada para detectar que el objeto es una colección genérica y qué tipos contiene, los dos elementos de información que necesito para serializarlo correctamente. Hasta la fecha, he estado usando la codificación del formulario

if (o is int) {// do something}

pero eso no parece funcionar con los genéricos.

¿Que recomiendas

EDIT: Gracias a Lucero, Me he acercado a la respuesta, pero estoy atrapado en este pequeño enigma sintáctico aquí:

if (t.IsGenericType) {
  if (typeof(List<>) == t.GetGenericTypeDefinition()) {
    Type lt = t.GetGenericArguments()[0];
    List<lt> x = (List<lt>)o;
    stringifyList(x);
  }
}

Este código no se compila, porque "lt "no está permitido ya que<T> argumento de unList<> objeto. Por qué no? ¿Y cuál es la sintaxis correcta?

Respuestas a la pregunta(3)

Su respuesta a la pregunta