2009-05-22 11 views
7

Utilizzando la sintassi C# di inizializzazione degli oggetti posso istanziare un oggetto anonimo come questo:Instantiating oggetto anonimo usando # oggetto la sintassi di inizializzazione C immagazzinate nella stringa

object empData = new { name = "bob", age = 30, salary = 100000 }; 

Ma cosa succede se ho l'inizializzatore memorizzato in una stringa, ad esempio:

string init = "{ name = \"bob\", age = 30, salary = 100000 }"; 

Qual è il modo migliore per convertire questa stringa in un'istanza dell'oggetto?

risposta

16

Le classi anonime sono C# syntactic sugar (vedere la sezione Note here). csc.exe crea una classe con campi privati ​​e una proprietà di lettura/scrittura con il tipo dedotto dal contesto. Tutti gli usi dell'oggetto sono, ancora una volta, dedotti.

Ciò significa che non è possibile creare una classe anonima in fase di esecuzione perché il CLR li vede non diversamente da qualsiasi altra classe (di nuovo, perché è lo zucchero sintattico C#).

Così, invece:

  • Utilizzare un Dictionary<string,object>
  • Usa JSON.NET, XML o qualcosa di simile che ha un certo schema già definito per l'analisi di una stringa per ottenere un oggetto. Ciò richiede tuttavia che le proprietà siano ben definite.
  • Usa System.Reflection.Emit per creare il tipo in fase di esecuzione, ma non vedo alcun reale beneficio per questo più solo un Dictionary<string,object>

Ho anche preoccupazioni di quello che stai facendo, perché questo come una stringa mezzo molto probabile per me che stai accettando l'input dell'utente di qualche tipo. Diffida dei problemi di sicurezza in qualunque cosa tu faccia.

+0

Argh ... hai ragione, sapevo che le classi anon venivano generate in fase di compilazione ma il mio cervello non ha fatto la connessione (Immagino che il lungo weekend sia in ritardo). Anche la tua preoccupazione per la sicurezza e l'input dell'utente è sicuramente valida. Ad ogni modo, la ragione per cui stavo facendo questo è perché l'API che stavo chiamando prendeva un oggetto anonimo. Ma si scopre che posso anche passare un dizionario in modo da risolvere il problema per me. Grazie. – DSO

+0

Sono assolutamente d'accordo. Mi piace usare molto XML usando il reflection per creare un xml personalizzato e complesso. Non è per tutti, ma se stai facendo un semplice XML, allora l'uso della serializzazione XML .NET dovrebbe essere sufficiente: D – pqsk

2

Non esiste un modo semplice e diretto per farlo. Fondamentalmente, hai queste opzioni:

  1. Analizza la stringa manualmente.
  2. Utilizzare il compilatore C# per compilare quell'oggetto come parte di un assieme e utilizzare la riflessione per calcolare il contenuto.
  3. (non sono sicuro che sia possibile, solo C# 4.0): utilizzare le classi del compilatore gestito C# 4.0 per analizzare l'espressione e dedurne il contenuto.

Nessuno dei quali è l'ideale secondo me. Prenderò in considerazione QueryString come coppie, XML o JSON o qualche altro formato che abbia parser disponibili là fuori, se hai l'opzione e considera la memorizzazione dei dati in un'istanza del dizionario invece di creare un oggetto per ogni espressione.

1

Non credo che questa domanda risponde la vostra di per sé, ma vi dirò perché non è possibile creare istanze anonimi di oggetti utilizzando stringhe in un modo così come lei suggerisce:

How do I create and access a new instance of an Anonymous Class passed as a parameter in C#?

I tipi anonimi non hanno campi pubblici, di conseguenza mentre è possibile farlo per un oggetto con nome, non è così semplice farlo per un tipo anonimo. Detto questo, non c'è niente che ti impedisca [come suggerito da BFree] di usare reflection per emettere l'MSIL per il tipo anonimo - il che non è esattamente semplice, ma neanche impossibile.

3

Il modo migliore per farlo è utilizzare la serializzazione. Ma ovviamente, questo non usa lo stesso formato di stringa che hai descritto.

L'inizializzatore dell'oggetto non deve contenere valori costanti.

string myName="bob"; 
int myAge=30; 
double mySalary=100000; 

object empData = new { name = myName, age = myAge, salary = mySalary }; 

Quindi nel tuo scenario si dovrà analizzare i singoli elementi dalla stringa, ed eseguire alcune conversioni su di loro per costringerli in tipi che si desidera.

Se non si è sposati con questo particolare formato di stringa, è possibile serializzare e deserializzare i propri oggetti e realizzare la stessa cosa utilizzando XML molto più facilmente.

+0

+1 per pensare al di fuori dei confini della domanda ... deve essere in ritardo – BenAlabaster

Problemi correlati