2012-03-06 15 views
11

Questo mi ha confuso un po '... Il tentativo di disporre di un XmlReaderImpossibile chiamare Dispose?

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

Fornisce il seguente errore:

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

tuttavia la seguente va bene:

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

Quando guardo la definizione in Reflector non riesco a capire perché non riesco a chiamare Dispose

XmlReader

Attuazione Smaltire:

Dispose

Chiunque può segnalare quello che mi manca?

+0

Si sta osservando lo smontaggio di 'XmlReader' di .NET 4. – leppie

risposta

18

Il problema è che XmlReader utilizza implementazione di interfaccia esplicita a implement IDisposable. Così si può scrittura:

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

Tuttavia, avrei fortemente suggerisco di usare una dichiarazione using comunque. Dovrebbe essere molto raro che chiami esplicitamente Dispose, diverso da un'altra implementazione Dispose.

MODIFICA: come indicato, questo è "corretto" in .NET 4.5, in quanto espone uno public parameterless Dispose method come da .NET 4.5 e l'implementazione dell'interfaccia esplicita. Quindi presumibilmente stai compilando .NET 4.0 o precedente (forse .NET 2.0 dato i tuoi tag) ma usando Reflector contro .NET 4.5?

+0

Questo sembra essere "risolto" in .NET 4. Mi chiedo quale fosse l'intenzione originale con l'implementazione esplicita? – leppie

+0

@leppie: Non sono sicuro, ma penso che sia vero per alcune classi - non è la prima volta che lo vedo. –

+1

'System.Xml' non è esattamente noto per il suo buon stile; p IIRC diversi' nuovi' membri ecc in .NET 1.x (non sono sicuro di quelli più recenti). – leppie

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

è esattamente equivalente a

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

La cosa più probabile è che non avete pubblicato tutto il codice - forse qualcun altro sta chiamando Dispose() sul vostro oggetto pure, causando un eccezione nella seconda chiamata a Dispose()?

+4

No, non è esattamente equivalente a quello. Gestisce la nullità e, se necessario, esegue l'installazione implicita di "IDisposable" a causa dell'implementazione esplicita dell'interfaccia, come nel caso specifico. –

+1

Pre-.NET 4.0, XmlReader implementa l'ID esplicitamente. Il tuo 'reader.Dispose()' dovrebbe essere '((IDisposable) reader) .Dispose()' – Joe

+3

'' La cosa più probabile è che tu non abbia pubblicato tutto il tuo codice '' Se lo avessi provato, quelli due righe che ha postato sono state sufficienti per mostrare il problema. – weston

Problemi correlati