2009-03-07 10 views
12

He leído que eliminar las referencias no utilizadas makes no difference al compilador, ya que ignora los ensamblajes que no están siendo referenciados en el código mismo.¿Cuál es el propósito de "eliminar referencias no utilizadas"

Pero me resulta difícil de creer porque entonces, ¿cuál es el verdadero propósito de Removing unused references? No tiene ningún efecto notable en el tamaño del ensamblaje generado o de otro modo. ¿O es este comportamiento inteligente limitado al compilador de C# (csc.exe) y no inherente a vbc.exe?

Si esta funcionalidad es tan inútil, ¿por qué la ofrece ReSharper como característica? ¿Por qué se proporciona en el cuadro de diálogo Configuración del proyecto de Visual Studio?

La única actividad que puedo pensar en dónde esto podría ser útil es durante el Despliegue. Las referencias (usadas o no) seguirán siendo copiadas por el instalador. Pero para los ensamblados que residen en el GAC (por ejemplo, ensambles BCL), esto tampoco sería un problema.

Respuesta

14

Impide que CLR cargue el módulo al que se hace referencia en el tiempo de ejecución. Esto reducirá el tiempo de inicio (ya que lleva tiempo cargar cada módulo). Dependiendo del tamaño del módulo, puede reducir notablemente el tiempo de inicio.

Una forma de probar esto es crear un proyecto de prueba de WinForms, agregar una referencia a un ensamblaje que no se usa (por ejemplo, System.Web) y ejecutarlo y conectarlo al ejecutable (por ejemplo, F5). Vea los módulos cargados (Depurar -> Windows -> Módulos) y verá que se cargó el ensamblado al que se hace referencia.

Si lo piensa bien, sería muy difícil para el CLR determinar si realmente se usa una dependencia (está en el manifiesto como una dependencia una vez que agrega una referencia) ... Especialmente porque el la ejecución de algunas rutas de código no puede conocerse de antemano ...

+1

¿Cómo va a cargar el CLR un módulo en tiempo de ejecución cuya referencia fue eliminada por una optimización del compilador? ¿Que me estoy perdiendo aqui? – Dan

+0

@Dan - Tampoco entiendo por qué esta respuesta recibió tantos votos hacia arriba, por lo que he leído en otras publicaciones, el compilador no incluirá la referencia de ensamblado en el resultado final si no se utiliza. Los conjuntos referenciados solo serán cargados por el JIT en la primera llamada a un método de ellos. La ventana de módulos cargados que esta respuesta brinda como prueba podría mostrar todas las referencias porque está en modo de depuración. – BornToCode

+0

@BornToCode Además, si 'es [es] difícil para el CLR determinar si realmente se usa una dependencia', ¿cómo funciona" Quitar referencias no utilizadas "? Determinar si se usa o no una referencia es simple: si ningún código hace referencia a algo en el espacio de nombres de ese ensamblaje, entonces no se utiliza. – Dan

12

Además de que los archivos de origen son más pequeños, creo que es mejor tener un archivo de origen limpio que no tenga ningún código ni referencias sin usar.

+0

Gracias, Cristophe, pero la pregunta sigue siendo ... ¿cómo/por qué es mejor? – Cerebrus

+2

Es mejor porque sus archivos de origen no se hincharán serán códigos/importaciones no utilizados y, por lo tanto, serán más fáciles de leer y comprender. Además, creo que el compilador tendrá menos trabajo y la compilación será un poco más rápida. (No estoy 100% seguro de eso y esto es específico del compilador) –

8

Visual Studio 2008 también tiene la función para eliminar las directivas de uso no utilizadas.

La eliminación del código no utilizado hace que el código sea más nítido, pero también puede reducir el riesgo de conflictos. A veces hay clases con el mismo nombre en diferentes conjuntos. Por ejemplo, hay una clase Image tanto en System.Drawing como en System.Web.UI.WebControls. Si tiene que usar directivas para ambos espacios de nombres y comienza a usar la clase Image, el compilador no puede decir cuál de los que usará.

+0

+1: reduce el riesgo de conflictos – Sung

6

Es una optimización para hacer que su proyecto se compile más rápido. Evita que el compilador cargue metadatos que nunca se usarán. Aunque es menor, supongo que en unos 50 mseg, dependiendo de la velocidad de tu disco duro y del estado de la memoria caché del sistema de archivos.

El compilador de C# es lo suficientemente inteligente como para emitir solo referencias de ensamblados en los metadatos de su ensamblado compilado para los ensamblados que realmente se usan. Por lo tanto, no generará imágenes nativas para ensamblajes que no use cuando ejecute Ngen.exe. El compilador JIT no se verá afectado de ninguna manera, solo carga ensamblajes según sea necesario para traducir el IL.

+0

¿Esto implica que cuando se carga un ensamblaje NGENed todos los ensamblados a los que se hace referencia también se cargan posteriormente? O en otras palabras: ¿la carga lenta de ensamblajes nativos no es posible? Al menos eso es lo que veo cuando comparo los ensamblajes cargados de mi aplicación (JITed vs. NGENed). – Yves

Cuestiones relacionadas