C #: Listar todas as classes na montagem

103

Eu gostaria de produzir (programaticamente - C #) uma lista de todas as classes em meu assembly.

Alguma dica ou código de amostra de como fazer isso? Reflexão?

Alex
fonte
Se sua intenção é examinar uma montagem que não é referenciada por seu projeto, veja minha resposta atualizada.
Thorarin

Respostas:

152

Use Assembly.GetTypes. Por exemplo:

Assembly mscorlib = typeof(string).Assembly;
foreach (Type type in mscorlib.GetTypes())
{
    Console.WriteLine(type.FullName);
}
Jon Skeet
fonte
1
Alguma sugestão para grandes montagens? Quando eu executo este código para um assembly de 13,8 MB, minha instância do VS trava pelo que parece indefinidamente. Eu tentei um pequeno assembly de 9 KB e funcionou muito bem. Eu sei o que você está pensando - por que você tem uma montagem de 13,8 MB - é parte da minha camada de dados gerada usando um modelo NetTeirs. Temos muitas mesas.
dyslexicanaboko
1
@dyslexicanaboko: Bem, se você tiver muitos tipos, demorará muito para enumerá-los todos. Quantos tipos existem em sua montagem? E o que você está fazendo com eles? (Tem certeza de que o problema está em extrair os tipos ou apenas o que você fará depois?)
Jon Skeet
Não consigo passar da chamada asm.GetTypes (), ela apenas trava - quero dizer, é obviamente o fato de que há muitos tipos - não posso fazer nada porque está se esforçando para tentar pegá-los todos . Minha CPU dispara para 30% em um dos meus 4 núcleos. Na verdade, estou apenas me perguntando se há uma maneira de dizer: "Ei - apenas olhe NESTE namespace" - tenho a impressão de que não é possível porque o método GetTypes () tem apenas um construtor vazio. Estou tentando fazer uma espécie de navegador de objetos.
dislexicanaboko
1
Bom ponto, eu não tentei isso ainda. Minha solução agora é apenas direcionar as classes diretamente usando asm.GetType (fullyQualifiedClassName) - isso funciona, mas mostrar uma lista de classes para o usuário não é possível, que é o que eu queria. A propósito, isso não é voltado para o cliente, estou usando internamente para mim e outros desenvolvedores.
dislexicanaboko
1
@DebugErr: Sim - é fácil fazer apenas classes se você quiser, mas meu palpite é que o OP provavelmente realmente queria todos os tipos.
Jon Skeet de
102

Eu gostaria apenas de acrescentar ao exemplo de Jon. Para obter uma referência para seu próprio conjunto, você pode usar:

Assembly myAssembly = Assembly.GetExecutingAssembly();

System.Reflection namespace.

Se você quiser examinar uma montagem à qual não tem referência, pode usar um dos seguintes:

Assembly assembly = Assembly.ReflectionOnlyLoad(fullAssemblyName);
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(fileName);

Se você pretende instanciar seu tipo assim que o encontrar:

Assembly assembly = Assembly.Load(fullAssemblyName);
Assembly assembly = Assembly.LoadFrom(fileName);

Consulte a documentação da classe Assembly para obter mais informações.

Depois de ter a referência ao Assemblyobjeto, você pode usar assembly.GetTypes()como Jon já demonstrou.

Thorarin
fonte
Como posso fazer referência a um assembly completamente diferente que está em minha solução?
Alex
13
A maneira mais fácil é usar typeofcom um tipo que você sabe que está naquela montagem e, em seguida, com a Assemblypropriedade, como no meu exemplo.
Jon Skeet
2
Se você quiser fazer referência a um assembly, digamos abc.dll, que está em sua solução e se você estiver bem codificando o nome do dll, outra abordagem para fazer referência ao assembly é: `Assembly assembly = Assembly.Load (" abc ");`
Kash
Ele carrega apenas a montagem atual. Eu tenho um aplicativo ou exe usando 4 dlls ou projetos. Como posso obter os nomes das classes dessas dlls?
Er Mayank
@JonSkeet Como isso seria possível em um ambiente c # "moderno"? Por exemplo, ao fazer o desenvolvimento UWP. UWP não tem o método GetExecutingAssembly ().
Daniel Armstrong