2009-11-04 26 views
14

Quando si implementa l'interfaccia ISerializable in C#, forniamo un costruttore che prende un oggetto SerializationInfo e poi lo interroga con vari metodi GetInt32, GetObject ecc. Per riempire i campi dell'oggetto che stiamo tentando di deserializzare.Perché SerializationInfo non ha i metodi TryGetValue?

Uno dei motivi principali per implementare questa interfaccia, piuttosto che utilizzando l'attributo [Serializable], è per la compatibilità all'indietro: se abbiamo aggiunto nuovi campi alla classe ad un certo punto, siamo in grado di prendere il SerializationException lanciata da una versione serializzata più vecchia della classe e gestirli in modo appropriato.

La mia domanda è la seguente: perché dobbiamo usare queste eccezioni per ciò che è, essenzialmente, il flusso di controllo? Se sto deserializzando un gran numero di classi che sono state salvate qualche tempo fa, potenzialmente ogni campo mancante in ogni classe genererà un'eccezione, causando prestazioni davvero pessime.

Perché la classe SerializationInfo non fornisce i metodi TryGetValue che restituirebbero semplicemente false se la stringa del nome non fosse presente?

+0

Chiedi chi implementato quella classe –

+4

beh forse sono qui: P –

risposta

23

È possibile scorrere i campi disponibili e utilizzare switch, anche se ...

  foreach(SerializationEntry entry in info) { 
       switch(entry.Name) { 
        ... 
       } 
      } 

Oppure si potrebbe usare protobuf-net ;-p

+2

cool; questo non sembra essere documentato nella documentazione VS2008. –

+1

concordato. Questo non sembra essere documentato da nessuna parte. Nulla sembra dire che SerializationInfo è enumerabile. Ma ha funzionato per me. –

+1

@Michael tranne [qui] (http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationinfo.getenumerator.aspx) ovviamente, o (@Joel) tornare a 1.1, [ qui] (http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationinfo.getenumerator (v = VS.71) .aspx) –

0

Ebbene nessuno ha risposto 'perché', ma io 'm indovinando che è indirizzata a MS ..

mio implementazione per chiunque abbia bisogno:

public static class SerializationInfoExtensions 
{ 
    public static bool TryGetValue<T>(this SerializationInfo serializationInfo, string name, out T value) 
    { 
     try 
     { 
      value = (T) serializationInfo.GetValue(name, typeof(T)); 
      return true; 
     } 
     catch (SerializationException) 
     { 
      value = default(T); 
      return false; 
     } 
    } 

    public static T GetValueOrDefault<T>(this SerializationInfo serializationInfo, string name, Lazy<T> defaultValue) 
    { 
     try 
     { 
      return (T) serializationInfo.GetValue(name, typeof(T)); 
     } 
     catch (SerializationException) 
     { 
      return defaultValue.Value; 
     } 
    } 
} 
Problemi correlati