2012-02-09 16 views
35

Ancora una volta sto spiegando una delle mie pressioni sul dizionario! Questa domanda è comparsa nella mia mente dalla risposta del mio previous question !!Come convertire la classe nel dizionario <string, string>?

Ora il punto effettivo è Posso convertire la classe nel dizionario?

nel dizionario Voglio che i miei proprietà della classe come KEY valore della proprietà particolare e come VALORE

Supponiamo che la mia classe è

public class Location 
{ 
    public string city { get; set; } 
    public string state { get; set; } 
    public string country { get; set; 
} 

Ora supponiamo miei dati è

city = Delhi 
state = Delhi 
country = India 

Ora puoi capire facilmente il mio punto di vista!

Voglio fare il dizionario! Quel dizionario dovrebbe essere come

Posso ottenere il valore! Ma come posso ottenere i nomi delle proprietà (non valore)?

Cosa devo codice per crearlo dinamico! Questo dovrebbe funzionare per ogni classe che voglio?

Si può capire questa domanda come

Come posso ottenere l'elenco di oggetti di particolare classe?

+0

Puoi provare a riformulare la domanda per favore? Non ho idea di cosa stai cercando di ottenere. – ilivewithian

+0

Insort! Voglio il nome di tutte le variabili di una particolare classe! È possibile ? – Chintan

+0

@NoOne Ho risposto, ma è necessario imparare qualcosa di più su OOP.Stai parlando di _properties_. E le "variabili" a livello di classe sono chiamate _fields_. È importante chiamare tutto con il suo nome per capire che sarebbe più facile di adesso! ;) –

risposta

88

Questa è la ricetta: 1 riflessione, 1 LINQ-to-Objects!

someObject.GetType() 
    .GetProperties(BindingFlags.Instance | BindingFlags.Public) 
      .ToDictionary(prop => prop.Name, prop => prop.GetValue(someObject, null)) 

Da quando ho pubblicato questa risposta ho controllato che molte persone pensano che sia utile. Invito tutti coloro che cercano questa soluzione semplice a controllare un altro Q & A in cui l'ho generalizzato in un metodo di estensione: Mapping object to dictionary and vice versa.

+0

Cosa succede se vedo proprietà "intrinseche" come "GenericEqualityComparer", piuttosto che proprietà che ho esplicitamente dichiarato? Ho provato 'BindingFlags.DeclaredOnly'. – drzaus

+0

** AGGIORNAMENTO ** non importa - ho scoperto che il metodo che utilizzava questa riflessione (stesso in un'estensione di oggetto) ha finito per chiamarsi con il risultato convertito, quindi la mia estensione veniva chiamata su un oggetto E POI sul dizionario risultante. – drzaus

+0

Non riesco a compilarlo in Unity3D, mi manca un riferimento all'assembly? – c0d3Junk13

13

Ecco un esempio con la riflessione senza LINQ:

Location local = new Location(); 
    local.city = "Lisbon"; 
    local.country = "Portugal"; 
    local.state = "None"; 

    PropertyInfo[] infos = local.GetType().GetProperties(); 

    Dictionary<string,string> dix = new Dictionary<string,string>(); 

    foreach (PropertyInfo info in infos) 
    { 
     dix.Add(info.Name, info.GetValue(local, null).ToString()); 
    } 

    foreach (string key in dix.Keys) 
    { 
     Console.WriteLine("nameProperty: {0}; value: {1}", key, dix[key]); 
    } 

    Console.Read(); 
+0

Questo mi ha salvato almeno un giorno di lavoro. Grazie mille vorrei votarti due volte se potessi! – Kibitz503

0
protected string getExamTimeBlock(object dataItem) 
{ 
    var dt = ((System.Collections.Specialized.StringDictionary)(dataItem)); 

    if (SPContext.Current.Web.CurrencyLocaleID == 1033) return dt["en"]; 
    else return dt["sv"]; 
} 
0

dare una prova.

public static Dictionary<string, object> ObjectToDictionary(object obj) 
    { 
     Dictionary<string, object> ret = new Dictionary<string, object>(); 

     foreach (PropertyInfo prop in obj.GetType().GetProperties()) 
     { 
      string propName = prop.Name; 
      var val = obj.GetType().GetProperty(propName).GetValue(obj, null); 
      if (val != null) 
      { 
       ret.Add(propName, val.ToString()); 
      } 
      else 
      { 
       ret.Add(propName, null); 
      } 
     } 

     return ret; 
    } 
0

Vorrei aggiungere un'alternativa alla riflessione, utilizzando JToken. Dovrai controllare la differenza di benchmark tra i due per vedere quale ha prestazioni migliori.

var location = new Location() { City = "London" }; 
var locationToken = JToken.FromObject(location); 
var locationObject = locationObject.Value<JObject>(); 
var locationPropertyList = locationObject.Properties() 
    .Select(x => new KeyValuePair<string, string>(x.Name, x.Value.ToString())); 

Nota questo metodo è il migliore per una struttura di classe piatta.

+0

'var locationObject = locationObject.Value ();'? –

Problemi correlati