2009-12-28 7 views
19

Muchas veces hay un método claro, que elimina todos los elementos de las colecciones, estos elementos también se eliminan.¿Llamar Clear también elimina los artículos?

igual,

toolStripMenuItem.DropDownItems.Clear(); 

es suficiente, o debería tener que llamar así:

foreach (ToolStripItem item in toolStripMenuItem.DropDownItems) 
{ 
    toolStripMenuItem.DropDownItems.Remove(item); 
    item.Dispose(); 
} 

Editar: Bueno ToolStripItem no es un ejemplo de una pregunta, para los que dice Clear es lo suficientemente Encontré otro ejemplo, TabControl también tiene colección de elementos y método claro. Pero los TabControls pueden tener controles complejos (al menos yo los tengo), que deben ser eliminados explícitamente (incluso si están Dispuestos automáticamente en algún punto por GC, porque toman una gran cantidad de memoria). Supongo que la mejor respuesta es divo comment para desechar los elementos, y luego llamar a clear.

+0

Creo que el autor es un desarrollador de C/C++ que "necesita" disponer de los recursos en cada función, incluso si en .NET no es una necesidad. Dudo sobre la necesidad de Finalizar/Eliminar elementos después de * Borrar * ing it de la colección. – serhio

+3

@serhio - en .NET, sigue siendo su trabajo llamar a 'Dispose()' en los recursos de 'IDisposable', o asegurarse de que 'Dispose()' sea llamado por algún otro código. –

+0

El uso de .NET Reflector es una buena forma de ver si 'ToolStripItemCollection.Clear()' en realidad llama a 'Dispose' en los elementos de la colección o no. Si miras la fuente desensamblada, verás que no. –

Respuesta

8

Q: ¿?

A: No se - Clear no dispone de los elementos (que podría ser utilizado en otras partes de la aplicación).

Entonces, si sus ToolStripItems son estándar .NET, ¿debería ser suficiente Clear? Después de reflexionar, diría "probablemente no".

Sí, esto es cierto que si va a tener ninguna referencia a la ToolStripItem en otra parte de su solicitud, el .NET garbagecollector destruirá (utilizar la clase destructor) de forma automática. Pero, no llamará al Dispose(true) método, que es, sin embargo, requerido para los componentes IDisposable del formulario.

Lea un proposito this y this.

En realidad, creo que va, sin embargo, tienen que explícitamente Dispose sus artículos, como Desechar método de ToolStrip hace (reemplazar este por yourToolStrip):

if (!this.Items.IsReadOnly) 
{ 
    for (int i = this.Items.Count - 1; i >= 0; i--) 
    { 
     this.Items[i].Dispose(); 
    } 
    this.Items.Clear(); 
} 

EDITAR

También creé the following thread para aclarar esta pregunta de manera más general.

+3

No, claro no será suficiente si los objetos en la colección necesitan eliminación. El finalizador * podría * disponer el objeto; sin embargo, no es determinista cuando ocurrirá esto y no es seguro que ocurra en absoluto (ver http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx: "The Finalize es posible que el método no se ejecute por completo o que no se ejecute en las siguientes circunstancias excepcionales ... " –

+0

Dudo sobre la necesidad de finalizar/desechar elementos después de * borrar * ing it de la colección. – serhio

+0

Hola serio, ¿no debería esto? 'Si tiene alguna referencia' debería ser 'Si no tiene ninguna referencia' –

0

No lo creo, más, puede causar muchos problemas lógicos porque es posible que tenga referencia a ese objeto en la colección para su uso posterior. Si no tiene referencias a esos objetos, el recolector de basura dispondrá de los objetos más adelante

+0

hm ... puntero en .NET no es una palabra correcta. – serhio

+0

corregido @serhio –

2

Debe confiar en la llamada Dispose() cuando se trata de memoria no administrada, recursos compartidos o áreas de gran memoria. No parece este caso.

2

Llamando Clear no descarta los artículos, pero elimina la referencia de la colección a los artículos. Si esa fuera la única referencia a los artículos, se recolectarán basura automáticamente en algún momento (que no se puede predecir, pero se puede controlar utilizando la clase GC).

+0

Confiar en el recolector de basura para su eliminación no es seguro. Vea mi comentario sobre la respuesta de serhio. –

+0

@divo: hay alguna necesidad de llenar su código con basura si su ToolStripItem es un objeto WinForm estándar. – serhio

+0

@serhio: en una aplicación de Windows Forms "normal" generalmente no es necesario llamar a 'Component.Descartar() 'explícitamente como ya se llamó, el formulario está cerrado (Ver el código generado por el diseñador detrás, sobrescribe' Dispose' y llama 'Dispose' a cada componente utilizado en el formulario). Sin embargo, si agrega y elimina componentes dinámicamente en el tiempo de ejecución, es su responsabilidad disponer explícitamente de estos componentes. –

Cuestiones relacionadas