2011-10-10 12 views
7

Estoy confundido acerca de los escenarios que usaría uno u otro.Assembly.GetTypes: ¿por qué usar esto si GetExportedTypes está disponible?

Si tiene un ensamblaje con algunos tipos públicos y privados (o internos), solo los tipos públicos deberían estar disponibles desde el exterior. Cualquier tipo que sea interno o privado, no debería estar disponible; de ​​hecho, su existencia no debería ser reconocible.

Por lo tanto, GetTypes y GetExportedTypes - en mi opinión, debería devolver la misma cosa.

Claramente estoy pensando en esto mal, ¿para qué sirve cada uno?

Gracias!

+1

Reflection también proporciona acceso a tipos no accesibles. –

+0

¡No está súper resuelto todavía! Pero acepté el más cercano. – Coopernick

Respuesta

4

La visibilidad en el nivel de idioma no tiene nada que ver con la visibilidad del tipo en el nivel de reflexión.

Toda la idea de la reflexión es que puedes ver todos los tipos, miembros, etc. e inspeccionarlos; decir para fines de generación de código o lo que sea. Igualmente tiene escenarios tales como dónde se usa InternalsVisibleToAttribute y, como han dicho otros, cuando necesita reflejar su propio conjunto. Todos son perfectamente legítimos y serían imposibles (lo que restringiría en gran medida el marco .Net) si no estuvieran disponibles.

Por lo tanto, el valor predeterminado debe devolver todos los tipos; solo cuando se intenta utilizar un tipo en tiempo de ejecución, la visibilidad entra en él. También puede ser lateral; el framework .Net se basa en algunos casos en los que se pueden crear instancias de tipos privados propios de otros ensamblados; y también puede omitir las comprobaciones de visibilidad en sus propios ensamblajes dinámicamente construidos. Utilizo esta característica en mi propio marco personalizado de IOC y DI escrito para nuestras aplicaciones internas para permitir a nuestros desarrolladores crear tipos completamente ocultos de código externo, pero aún utilizables dentro de sus aplicaciones.

0

Para montajes externos que de hecho serían el caso, pero ¿qué sucede si llama a GetTypes en su propio ensamblaje?

Luego verá las privadas y las internas también, lo cual es lógico.

+1

esto no es cierto. Consulte la documentación de MSDN ... – Yahia

6

Desde el MSDN docs:

Assembly.GetTypes Método
Valor de retorno Tipo: System.Type []
Una matriz que contiene todos los tipos que se definen en esta asamblea.

Desde el MSDN docs:

Assembly.GetExportedTypes Método
Valor de retorno
Tipo: System.Type []
Una matriz que representa los tipos definidos en este montaje que son visibles fuera del ensamblaje.

Así que la llamada se GetTypes() de hecho le dará todas las tipos definidos en una asamblea - ya sean "visibles" y instanciable a usted o no. Puede parecer extraño, pero ¿qué ocurre si desea inspeccionar usted mismo, su propia asamblea (o una asamblea en el mismo espacio de nombres como su código)? Debe poder ver todo, si es necesario.

+0

Bien, gracias, pero estoy más interesado en POR QUÉ, desde la perspectiva del cliente: si construyo y emite un Ensamblaje, solo la interfaz pública debe ser visible. . Dicho esto, tienes razón al inspeccionar tu propia asamblea. – Coopernick

0

GetExportedTypes() no incluye tipos protegidos/privados. GetTypes() incluye todos los tipos.

Con respecto a los tipos internal, no está clara la documentación de MSDN de GetExportedTypes().

0

Si quiere todos los tipos públicos, puede usar GetExportedTypes, pero si quiere también todos los otros tipos, puede usar GetTypes. Incluso si un tipo es privado o interno, puede crear instancias nuevas y usarlo a través de Reflection y Dynamic, por lo que no veo que ninguno de estos dos sea redundante.

0

Estaba investigando una API web bug que se encontró con esto y encontré una diferencia muy importante entre Assembly.GetExportedTypes y 'Assembly.GetTypes`. Está en la documentación pero no está muy claro.

Assembly.GetExportedTypes arroja una 'FileNotFoundException' si alguno de los ensamblajes dependientes no se puede cargar. 'Assembly.GetTypes throws ReflectionTypeLoadException which contains types that are loaded successfully. So, if you want to succeed even if some of the types in the assembly cannot be loaded, you should use GetTypes and not GetExportedTypes`.

Este trozo de código no funcionaría como Assembly.GetExportedTypes no arroja ReflectionTypeLoadException.

 Type[] types; 
     try 
     { 
      types = assembly.GetExportedTypes(); 
     } 
     catch (ReflectionTypeLoadException e) 
     { 
      types = e.Types; 
     } 
Cuestiones relacionadas