suggerisce la struttura per le classi che mappano a json con dati dinamici senza utilizzare riferimenti dinamici o oggetto

0

questo è un tipo di dati che devo de-serializzare

{
    "id": "M:11427",
    "title": "DAX30",
    "nextStartId": "S:727831",
    "sections": [
        {
            "type": "HIGHLIGHTS",
            "baseResults": [ values of type highlights ],
            "hasMore": true
        },
        {
            "type": "CHART",
            "hasMore": false,
            "chartTypes": [ string values ]
        },
        {
            "type": "TWEETS",
            "baseResults": [ values of type tweets ],
            "hasMore": true
        }]
}

Devo serializzare & deserializzare tutti. Voglio creare qualcosa che possa contenere i valori corrispondenti a baseResults.

c'è una classe principale che rappresenta l'intero json

class Data 
{
...
ObservableCollection<Section> sections{get;set;}
...
}

quindi c'è una classe che rappresenta i dati nella sezioni array di json principale

class Section
{
string type{get;set;}// thi elements decides what kind of data would be in baseResults
dynamic baseResults{get;set;} //it should hold ObservableCollection of either Highlights or Tweets etc.
}

la classe base per il tipo di dati provenienti dall'array baseResults è una classe astratta class CategoryData e i suoi figli sono class Highlights & class Tweets

Sto utilizzando dynamic poiché non posso assegnare ObservableCollection<CategoryData> a ObservableCollection<Highlights> . Ma non voglio usare questo tipo di oggetto dinamico o di oggetto invece voglio qualcosa di rilevante. per favore suggeriscimi quale potrebbe essere un approccio migliore per questo problema.

    
posta Ankit 21.03.2014 - 13:14
fonte

3 risposte

1

Se ti capisco correttamente, stai cercando di trovare un modo tipicamente statico per dire "un valore di tipo Section può essere un valore di tipo Highlights , Chart o Tweets ". Esistono molti termini per questo, tra cui unione con tag, unione discriminata, variante o tipo di somma ma si riferiscono tutti allo stesso concetto. I tipi di somma sono una caratteristica standard nei linguaggi di programmazione funzionale tipizzati staticamente, ma con un po 'di ingenuità puoi eseguire il rollover in C # . Usando questa risposta come modello e aggiungendo sealed per assicurarti che nessuno aggiunga sottoclassi extra, il tuo tipo Section sarà simile a questo:

public abstract class Section
{
    // Prevent subclassing outside of this scope
    private Section() {}

    // Subclass implementation calls the appropriate function.
    public abstract R Match<R>(Func<H, R> IfHighlight, Func<C, R> IfChart, Func<T, R> IfTweet);

    // Convenience wrapper for when the caller doesn't want to return a value
    // from the match expression.
    public sealed void Match(Action<H> IfHighlight, Action<C> IfChart, Action<T> IfTweet)
    {
        this.Match<int>(
            IfHighlight: Section => { IfHighlight(Section); return 0; },
            IfChart: Section => { IfChart(Section); return 0; },
            IfTweet: Section => { IfTweet(Section); return 0; }
        );
    }

    // From here on down, you define your specific types as usual, and override Match to call
    // the correct function

    public sealed class Highlight : Section
    {
        // Implementation goes here

        public override R Match<R>(Func<H, R> IfHighlight, Func<C, R> IfChart, Func<T, R> IfTweet)
        {
            return IfHighlight(this);
        }
    }

    public class Chart : Section
    {
        // Implementation goes here

        public override R Match<R>(Func<H, R> IfHighlight, Func<C, R> IfChart, Func<T, R> IfTweet)
        {
            return IfChart(this);
        }
    }

    public class Tweet : Section
    {
        // Implementation goes here

        public override R Match<R>(Func<H, R> IfHighlight, Func<C, R> IfChart, Func<T, R> IfTweet)
        {
            return IfTweet(this);
        }
    }
}

Con questo, puoi dichiarare le variabili di tipo Section e agire su di esse passando 3 funzioni ai metodi Match :

Section section = deserializeJson()
section.Match(
    IfHighlight: highlight => /* code to use if you get a Highlight */
    IfChart: chart => /* ... */
    IfTweet: tweet => /* ... */
);

Potresti altrettanto facilmente avere una raccolta di Section se operare su di essi in quel modo quando esegui un'iterazione.

    
risposta data 21.03.2014 - 14:24
fonte
0

Che ne dici di usare i generici:

class Section<TCategoryData> where TCategoryData : CategoryData
{
    string type{get;set;}
    ObservableCollection<TCategoryData> baseResults{get;set;}
}


class HighlightSection : Section<Highlights> {}

class TweetSection : Section<Tweets> {}
    
risposta data 21.03.2014 - 13:29
fonte
0

Dovresti scegliere il sottotipo concreto di Section PRIMA di creare l'istanza. La proprietà type non dovrebbe nemmeno essere in Section e dovrebbe essere legata alla sottoclasse dell'istanza.

Ma come farlo dipende da come stai facendo la serializzazione e la deserializzazione.

    
risposta data 21.03.2014 - 15:17
fonte

Leggi altre domande sui tag