Pregunta

recibo una advertencia cuando corro un poco de código a través de la utilidad de análisis de código de Visual Studio, que no estoy seguro de cómo resolver. Tal vez alguien aquí ha encontrado con un problema similar, resuelto, y está dispuesto a compartir su visión.

estoy programando una célula a medida pintados utilizado en un control DataGridView. Los asemeja código:

public class DataGridViewMyCustomColumn : DataGridViewColumn
{
    public DataGridViewMyCustomColumn() : base(new DataGridViewMyCustomCell())
    {
    }

Se genera la advertencia siguiente:

CA2000: Microsoft.Reliability: En el método 'DataGridViewMyCustomColumn.DataGridViewMyCustomColumn ()' System.IDisposable.Dispose llamada en el objeto 'nuevo DataGridViewMyCustomCell ()' antes de todas las referencias a ella están fuera del alcance <. / p>

Yo entiendo que me está advirtiendo DataGridViewMyCustomCell (o una clase que hereda de) implementa la interfaz IDisposable y el método Dispose () debe ser llamado a limpiar cualquier recurso reclamadas por DataGridViewMyCustomCell cuando ya no lo es.

Los ejemplos que he visto en Internet sugieren el uso de un bloque de alcance el tiempo de vida del objeto y que el sistema disponga de forma automática, pero la base no se reconoce cuando se mueve en el cuerpo del constructor por lo que no puede escribir un bloque usando alrededor de ella ... lo que no estoy seguro de que me gustaría hacer de todos modos, ya no sería que instruyen el tiempo de ejecución para liberar el objeto que todavía podría ser utilizado más adelante dentro de la clase base?

Mi pregunta entonces, es el código está bien como es? O, como no podía ser rediseñado para resolver la advertencia? No quiero suprimir la advertencia a menos que sea realmente apropiado hacerlo.

¿Fue útil?

Solución

Si está utilizando Visual Studio 2010 y luego CA2000 es completamente roto. También se puede romper en otras versiones de FxCop (también denominado análisis de código), pero VS2010 es el único que puede dar fe de. Nuestro código base está dando advertencias CA2000 de código como este ...

internal static class ConnectionManager 
{
    public static SqlConnection CreateConnection()
    {
         return new SqlConnection("our connection string");
    }
}

... lo que indica que no está siendo dispuesta la conexión antes de que se sale del ámbito en el método. Bueno, sí, eso es cierto, pero no está fuera del alcance para la aplicación ya que es devuelto a la persona que llama - que es el punto central del método! De la misma manera, el argumento del constructor no va fuera de su alcance, pero se está pasando a la clase base, por lo que es un falso positivo de la regla más que un problema real.

Esto solía ser una regla útil, pero ahora lo único que puede hacer es apagarlo hasta que lo arreglan. Lo cual es lamentable, ya que las (muy pocos) positivos reales son cosas que deben ser corregidos.

Otros consejos

No hay manera segura y elegante para tener un constructor encadenado pasar un nuevo objeto IDisposable al constructor de base, ya que como se nota que no es posible envolver la llamada al constructor encadenado en cualquier tipo de bloque try finally. Hay un enfoque que es seguro, pero es apenas elegante: definir un método de utilidad algo como:

internal static TV storeAndReturn<TR,TV>(ref TR dest, TV value) where TV:TR
{ 
  dest = value; return value;
}

Tener el aspecto constructor de algo como:

protected DataGridViewMyCustomColumn(ref IDisposable cleaner) : 
   base(storeAndReturn(ref cleaner, new DataGridViewMyCustomCell()))
{
}

Código que necesita un nuevo objeto tendría que llamar a un método de fábrica estática pública que llamar al constructor apropiado dentro de un bloque try / finally cuya línea principal sería nulo a cabo cleaner justo antes de que terminó, y cuyo bloque finally llamaría Dispose en cleaner si no es nulo. A condición de que cada subclase define un método de fábrica similares, este enfoque se asegurará de que el nuevo objeto IDisposable conseguirá dispuesto incluso si se produce una excepción entre el tiempo que ha creado y el tiempo de encapsular el objeto está expuesto al código de cliente. El patrón es feo, pero no estoy seguro de cualquier otro patrón más agradable aseguraría corrección.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top