Domanda

Ho un grafico ad oggetti piuttosto consistente che ho serializzato su un file tramite DataContractSerializer. Ora voglio presentare un elenco di questi file all'utente tra cui scegliere. In questo elenco, voglio mostrare alcuni dettagli sul file, che sono proprietà dell'oggetto root. Non voglio caricare l'intero grafico in memoria, poiché mi interessa solo visualizzare le proprietà del nodo principale.

Qualcuno conosce un modo per controllare la "profondità" della deserializzazione in modo che io possa semplicemente estrarre l'oggetto root dal file e saltare i bambini? Preferirei evitare di trattare il file come XML non elaborato, dal momento che non sto eseguendo manipolazioni XML non elaborate da nessun'altra parte e sarebbe un ulteriore ramo di codice che devo mantenere sincronizzato.

La mia unica idea in questo momento è creare un "riepilogo" compatibile " oggetto contenente solo le proprietà a cui sono interessato e nessuno dei figli e deserializza il file in quello. Questo dovrebbe saltare i bambini poiché non sono rilevanti per l'oggetto di riepilogo.

C'è un modo migliore per raggiungere questo obiettivo?

Aggiornamento / Chiarimento : gli attributi non sono la risposta che sto cercando. Per prima cosa, impediranno il "extra" le proprietà finiscono nel file quando l'oggetto è stato serializzato per la prima volta.

In secondo luogo, sono più permanenti di quello che sto cercando di fare. Alla fine, voglio deserializzare l'intero file, ma non a questo punto. Sto cercando di mostrare un elenco riepilogativo dei file che l'utente sceglierà per l'importazione. Durante l'importazione, avrò bisogno di tutti i bambini e i nipoti. È solo eccessivo durante il passaggio 1. Questi sono file potenzialmente di grandi dimensioni, quindi deserializzandone completamente alcuni solo per poter visualizzare le informazioni di intestazione non funzionerà.

Speriamo che chiarisca qualsiasi confusione sulla domanda originale.

È stato utile?

Soluzione

È praticamente il modo in cui vuoi farlo. DataContractSerializer ha lo scopo di gestire questa situazione, in cui è necessario tipi concettualmente uguali, ma tipi diversi dal punto di vista del CLR che si desidera serializzare tra loro.

Detto questo, basta creare l'oggetto con un sottoinsieme simile di proprietà che si desidera serializzare e passare quel tipo a DataContractSerializer.

Assicurati che sul " sommario " tipo di impostazione delle proprietà dell'attributo DataContract (nonché di eventuali attributi DataMember o DataContract sui figli esposti), in particolare le proprietà Nome e Spazio dei nomi in modo da riflettere il nome e lo spazio dei nomi del tipo non di riepilogo (poiché devono corrispondere) .

Altri suggerimenti

La mia prima raccomandazione sarebbe quella di fare la manipolazione XML se vuoi solo estrarre alcuni dettagli dal nodo radice. Un'altra possibilità, sebbene non conosca le implicazioni relative alle prestazioni, è utilizzare le funzionalità di controllo delle versioni di DataContractSerializer per questo problema. Sul contratto dati, contrassegnare tutti i campi tranne quelli necessari nel riepilogo come Facoltativo. Quindi, copia il contratto dati come un'altra classe, tralasciando i campi opzionali. Deserializzare il nuovo contratto dati più piccolo.

class Program
{
    static void Main(string[] args)
    {
        Person a = new Person();
        Person b = new Person();
        a.Name = "Mike";
        b.Name = "Joe";
        b.Parent = a;

        DataContractSerializer dtc = new DataContractSerializer(typeof(Person));

        StringBuilder sb = new StringBuilder();
        using (XmlWriter xr = XmlWriter.Create(sb))
        {
            dtc.WriteObject(xr, b);
        }

        object n;

        DataContractSerializer dtc2 = new DataContractSerializer(typeof(TinyPerson));

        using (XmlReader xr = XmlReader.Create(new StringReader(sb.ToString())))
        {
            n = dtc2.ReadObject(xr);
        }

    }
}

[DataContract(Name="Person")]
public class Person
{
    [DataMember]
    public string Name;

    [DataMember(IsRequired=false)]
    public Person Parent; 
}


[DataContract(Name = "Person")]
public class TinyPerson
{
    [DataMember]
    public string Name;

}

puoi controllare la tua serializzazione usando gli attributi. leggi di più qui

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top