2011-09-21 17 views
7

Por consejo de análisis de código en VS para llamar a Dispose en un objeto (que no estaba previuosly) que terminó con un método que contiene lo siguiente:deshacerse de una HtmlControl

using (var favicon = new HtmlLink 
         { 
          Href = "~/templates/default/images/cc_favicon.ico" 
         }) 
{ 
    favicon.Attributes.Add("rel", "shortcut icon"); 
    Header.Controls.Add(favicon); 
} 

Esto me confundió un poco, si Dispongo este objeto después de agregarlo a la colección Controls, ¿es una buena idea?

¿Cómo funciona esto? ¿Es porque el método Controls.Add elimina el objeto después de su uso en lugar de aferrarse a él?

+2

¿Realmente R # sugiere que debe deshacerse del 'HtmlLink'? ¿Puedes captura de pantalla eso? Eso no debería suceder. – bzlm

+0

@bzlm, voy a reformular, me da la opción de refactorizar en un uso, disculpe la confusión. – Mantorok

+1

, entonces sus preocupaciones son correctas.No debe eliminar los controles de ASP.NET Web Form que agrega a la colección de control. Y como nota general, las opciones proporcionadas por R # no siempre son aplicables; deberías usarlos con precaución. :) Si pruebas alt-enter en muchas cosas diferentes en tu código, notarás rápidamente que esto es así. – bzlm

Respuesta

2

yo diría que este código no debe trabajar, pero si usted dice que está funcionando entonces las únicas cosas que se me ocurren son:

  • Header.Controls.Add agregar una copia del objeto por lo que no hay problema para deshacerse del original.
  • El método Dispose no limpia nada que se use más adelante.

Espero que esto ayude.

+3

es el último Agregar no copia el objeto –

+0

No estoy seguro de por qué alguien me votó negativamente . Me gustaría argumentar por qué crees que mi respuesta no es correcta. Por favor dime. –

+0

No te recriminé, pero supongo que el DV podría ser porque la primera viñeta es incorrecta –

1

Si se llama a un método en favicon que utiliza cualquiera de los recursos no administrados, dará una excepción.

De MSDN:

Puede crear una instancia del objeto de recurso y luego pasa la variable de la instrucción using , pero esto no es una buena práctica. En este caso, el objeto permanece en el alcance después de que el control deja el bloque que usa incluso aunque probablemente ya no tendrá acceso a sus recursos no administrados. En otras palabras, ya no estará completamente inicializado. Si intenta utilizar el objeto fuera del bloque de uso, corre el riesgo de provocar una excepción . Por este motivo, generalmente es mejor crear el objeto en la instrucción using y limitar su alcance a usando el bloque.

using statement msdn

+0

Esto es interesante, porque cada control tiene un método Render en ASP.Net, entonces, ¿cómo lo logra en un objeto eliminado? – Mantorok

+0

Sí, tienes suerte si todavía funciona. Se puede romper con cualquier actualización o cambio posterior. – Peter

+1

¿Crees que Code Analysis lo sabe? ¿O fue solo suerte? – Mantorok

0

Supongo que el análisis del código le dio CA2000: Dispose objects before losing scope antes de cambiar el código. El problema es que no debe deshacerse de su objeto porque quiere usarlo incluso después de regresar del método (se ha agregado a una colección).

Puede suprimir el mensaje usando el SuppressMessage attribute o se puede reescribir su código para ser realmente paranoico:

var favicon = new HtmlLink { Href = "~/templates/default/images/cc_favicon.ico" }; 
try { 
    favicon.Attributes.Add("rel", "shortcut icon"); 
} 
catch { 
    favicon.Dispose(); 
    throw; 
} 
Header.Controls.Add(favicon); 

El flujo normal de este código añade favicon a la colección que es el responsable de la eliminación él. Sin embargo, el flujo anómalo donde favicon.Attributes.Add arroja una excepción eliminará favicon antes de propagar la excepción.

En la mayoría de los casos, dado que el recolector de basura hará su trabajo con el tiempo, no necesita la versión paranoica del código.

Cuestiones relacionadas