Best way to test if a Type is a collection

I think you're over complicating this a bit. If you really want to use IEnumerable but exclude System.String, why not just do that directly in code?

public static bool IsCollection(object obj) {
  return obj is IEnumerable && !(obj is String);
}

If you really only want to test:

bool isCollection = obj.GetType().GetInterfaces()
    .Any(iface => iface.GetGenericTypeDefinition() == typeof(ICollection<>))

But frankly, if you really only want to special-case string (why, by the way?), then just do so. If you test for ICollection<>, you will treat the result of a LINQ query as "non-collection", for example, for no good reason.