Ottieni dati dall'array di byte

0

Ho un byte array e un valore che definisce il tipo di dati memorizzati in esso ( string , int , ...). Qual è il modo migliore per ottenere questi dati? Ho due opzioni nella mia mente:

  1. Chiama un metodo che dia il tipo di dati e in base a quella chiamata un metodo che mi fornisce i dati corretti.
  2. Chiama un metodo che restituisce entrambi i dati (come object ) e anche il tipo di dati ( DateTime , float[] , ...).

Non sono sicuro che ci sia qualcosa di meglio, né quale sia uno di questi metodi migliore. Se
Type GiveMeDataType(); e ad es. string GiveMeString();
oppure
MyClass GiveMeData(); con MyClass { public Type DataType; public object Data; }

Vorrei adottare l'approccio migliore per la migliore leggibilità e manutenibilità (aggiungere supporto per tipi di dati aggiuntivi e così via), quindi non penso che troppe dichiarazioni switch in diverse parti del codice siano le migliori cosa da fare.

    
posta Artholl 25.07.2018 - 13:01
fonte

2 risposte

1

Penso che uno schema generale per questo sia il seguente

public interface IData
{
    Type Type {get;set;}
    byte[] Data {get;set;}
}

e poi molti:

public interface IDataConverter<T>
{
    T Convert(byte[] data);
    bool CanConvert(Type type);
}

Quindi puoi creare un IDataConverter per qualunque tipo tu voglia, e il convertitore ha una lista di questi che attraversa, chiamando CanConvert. Se restituisce true, chiama la funzione Converti e restituisce il risultato

class Converter
{
    private List<object> converters;
    public void AddConverter<T>(IDataConverter<T> converter)
    {
        this.converters.Add(converter);
    }
    public T Convert<T>(IData data) where T:class
    {
        var ret = converters
                .Select(i => ((dynamic)i))
                .Where(i => i.CanConvert(data.Type))
                .FirstOrDefault()?
                .Convert(data.Data)
                ;

        return ret as T;
    }
}

Modifica: come si può vedere lo shoehorning nel tipo generico è difficile. Probabilmente stai meglio usando lo stesso modello ma solo restituendo l'oggetto

    
risposta data 25.07.2018 - 15:40
fonte
1

Se hai bisogno di fare un comportamento diverso in fase di esecuzione a seconda del tipo di dati, non sarai in grado di evitare un qualche tipo di commutazione, anche se questo non deve essere letteralmente un'istruzione switch.

Per i dati stessi, il secondo ha il vantaggio che puoi passare il DynamicData (o qualsiasi altra cosa tu chiami la coppia Tipo / oggetto) più avanti per essere gestito più tardi, ma avrei anche un metodo diretto per quando il il tipo è noto:

DynamicData GiveMeData();
T GiveMeData<T>(); 

Mentre una funzione generale per ottenere i dati non può fare più di questo, è possibile modificare i consumatori dei dati per gestire i diversi tipi in modo dinamico. Ad esempio:

interface IDataConsumer
{
   IResult Consume(DynamicData data);
}

...

Dictionary<Type,IDataConsumer> consumers = ...;
var data = dataSource.GiveMeData();
var result = consumers[data.DataType].Consume(data);

Sotto il cofano, in pratica, è ancora un'affermazione, ma è molto più facile da aggiungere in futuro.

E, naturalmente, se uno qualsiasi dei tipi di dati condivide la funzionalità, puoi farli implementare un'interfaccia comune e gestirli tutti insieme.

    
risposta data 25.07.2018 - 20:15
fonte

Leggi altre domande sui tag