If you're talking about browsing an assembly at development time, then a static analysis tool like Reflector (as Agent_9191 suggests) is your best bet. If you're looking to do it at runtime, then reflection is the way to go. Either way, you need to define the scope of your search: what assemblies do you want to look through?
At development time, this is probably easy, and Reflector will let you easily specify these by loading the assemblies into its viewer. At runtime, this can be more difficult. To avoid greedily loading all sorts of otherwise useless assemblies, I'll assume you want to browse through all currently loaded assemblies, but this may not be correct. For this reason, I'll break this up into two functions:
public static IEnumerable<Type> GetImplementations(Type interfaceType)
{
// this will load the types for all of the currently loaded assemblies in the
// current domain.
return GetImplementations(interfaceType, AppDomain.CurrentDomain.GetAssemblies());
}
public static IEnumerable<Type> GetImplementations(Type interfaceType, IEnumerable<Assembly> assemblies)
{
return assemblies.SelectMany(
assembly => assembly.GetExportedTypes()).Where(
t => interfaceType.IsAssignableFrom(t)
);
}