2012-02-09 22 views
35

¡De nuevo, estoy explicando uno de mis deseos sobre el Diccionario! ¡Esta pregunta es popuped en mi mente de la respuesta de mi previous question !!Cómo convertir clases en Dictionary <string, string>?

Ahora el punto real es ¿Puedo convertir Clase en Diccionario?

En Diccionario Quiero que mis propiedades de la clase como CLAVE valor de propiedad particular y como VALOR

Supongamos que mi clase es

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

Supongamos ahora que mis datos son

city = Delhi 
state = Delhi 
country = India 

¡Ahora puedes entender mi punto fácilmente!

I want to make Dictionary! Ese diccionario debería ser como

¡Puedo obtener el valor! ¿Pero cómo puedo obtener nombres de propiedad (sin valor)?

¡Qué código debo tener para crearlo dinámico! Eso debería funcionar para cada clase que quiero?

Se puede entender esta cuestión como

¿Cómo puedo obtener la lista de propiedades de una clase particular?

+0

¿Puedes intentar cambiar la pregunta por favor? No tengo una idea real de lo que estás tratando de lograr. – ilivewithian

+0

Insort! ¡Quiero el nombre de todas las variables de una clase particular! Es posible ? – Chintan

+0

@NoOne Te he respondido, pero necesitas aprender algo más sobre OOP.Estás hablando de _properties_. Y las "variables" a nivel de clase se llaman _fields_. ¡Es importante llamar a todo por su nombre como si comprendieras que es más fácil que ahora! ;) –

Respuesta

88

Esta es la receta: 1 reflexión, 1 LINQ-to-Objects!

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

Desde que publiqué esta respuesta He comprobado que muchas personas encuentran útil. Invito a todos los que buscan esta sencilla solución a verificar otra Q & A donde la generalicé en un método de extensión: Mapping object to dictionary and vice versa.

+0

¿qué sucede si veo propiedades "intrínsecas" como "GenericEqualityComparer", en lugar de las propiedades que declaro explícitamente? He intentado 'BindingFlags.DeclaredOnly'. – drzaus

+0

** ACTUALIZACIÓN ** nevermind: descubrí que el método que utilizaba esta reflexión (en sí mismo en una extensión de objeto) terminaba llamándose a sí mismo con el resultado convertido, por lo que se llamaba a mi extensión sobre un objeto Y LUEGO sobre el diccionario resultante. – drzaus

+0

No puedo compilar esto en Unity3D, ¿me falta una referencia de ensamblado? – c0d3Junk13

13

Aquí un ejemplo con la reflexión sin 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

Esto me ahorró al menos un día de trabajo. Muchas gracias, ¡te votaría dos veces si pudiera! – 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

seguirlo.

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

Me gustaría agregar una alternativa a la reflexión, utilizando JToken. Deberá verificar la diferencia de referencia entre los dos para ver cuál tiene un mejor rendimiento.

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())); 

Tenga en cuenta que este método es mejor para una estructura de clase plana.

+0

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

Cuestiones relacionadas