2012-03-06 15 views
11

Éste me ha confundido un poco ... El intento de disponer de un XmlReader¿No se puede llamar a Dispose?

XmlReader reader = XmlReader.Create(filePath); 
reader.Dispose(); 

proporciona el siguiente error:

'System.Xml.XmlReader.Dispose(bool)' is inaccessible due to its protection level

sin embargo, la siguiente es bien:

using(XmlReader reader = XmlReader.Create(filePath)) 
{ 
} 

Cuando miro la definición en Reflector no puedo entender por qué no puedo llamar Eliminar

XmlReader

Implementación de Desechar:

Dispose

Puede alguien señalar lo que me falta?

+0

Está buscando el desmontaje de .NET 4 'XmlReader'. – leppie

Respuesta

18

El problema es que XmlReader utiliza implementación de interfaz explícita a implement IDisposable. Por lo que puede escritura:

XmlReader reader = XmlReader.Create(filePath); 
((IDisposable)reader).Dispose(); 

Sin embargo, me gustaría sugerir fuertemente el uso de una declaración using de todos modos. Debería ser muy raro que llame al Dispose explícitamente, excepto en otra implementación Dispose.

EDITAR: Como se señaló, esto es "fijo" en .NET 4.5, en el sentido de que expone un public parameterless Dispose method a partir de .NET 4.5, así como la implementación explícita de la interfaz. Así que presumiblemente compilas contra .NET 4.0 o anterior (tal vez .NET 2.0 dado tus etiquetas) pero usando Reflector contra .NET 4.5?

+0

Esto parece estar 'arreglado' en .NET 4. Me pregunto cuál fue la intención original con la implementación explícita. – leppie

+0

@leppie: No estoy seguro, pero creo que es cierto para algunas clases: esta no es la primera vez que la veo. –

+1

'System.Xml' no se conoce exactamente por su buen estilo; p IIRC varios miembros' nuevos', etc. en .NET 1.x (no estoy seguro de los más nuevos). – leppie

-2
using(XmlReader reader = XmlReader.Create(filePath)) 
{ 
    foo(reader); 
} 

es exactamente equivalente a

XmlReader reader = XmlReader.Create(filePath); 
try 
{ 
    code(reader); 
} 
finally 
{ 
    if(reader != null) 
    ((IDisposable)reader).Dispose(); 
} 

Lo más probable es que no se ha publicado todo el código - tal vez alguien más está llamando a Dispose() en el objeto, así, causando una excepción en la segunda llamada a Dispose()?

+4

No, no es exactamente equivalente a eso. Maneja la nulidad e implícitamente lanza a 'IDisposable' si es necesario debido a la implementación explícita de la interfaz, que es el caso aquí. –

+1

Pre-.NET 4.0, XmlReader implementa IDisposable explícitamente. Tu 'reader.Dispose()' debe ser '((IDisposable) reader) .Dispose()' – Joe

+3

'' Lo más probable es que no hayas publicado todo tu código '' Si lo hubieras probado, esos dos líneas que publicó fueron suficientes para mostrar el problema. – weston

Cuestiones relacionadas