valor obtener modificar llenar iterar ejemplos diccionario c# .net linq dictionary anonymous-types

obtener - modificar valor diccionario c#



Un diccionario donde el valor es un tipo anónimo en C# (4)

¿Es posible en C # crear un System.Collections.Generic.Dictionary<TKey, TValue> donde TKey es una clase no condicionada y TValue ? Una clase anónima con varias propiedades, por ejemplo, el nombre de columna de la base de datos y su nombre localizado.

Algo como esto:

new { ID = 1, Name = new { Column = "Dollar", Localized = "Доллар" } }


Como said , no puedes declarar tal bestia, pero sí puedes crear una:

static IDictionary<TKey, TValue> NewDictionary<TKey, TValue>(TKey key, TValue value) { return new Dictionary<TKey, TValue>(); } static void Main(string[] args) { var dict = NewDictionary(new {ID = 1}, new { Column = "Dollar", Localized = "Доллар" }); }

No está claro por qué querrías usar un código como este.


Creo que ASP.NET MVC no salió en el momento en que se hizo esta pregunta. Convierte objetos anónimos a diccionarios internamente.

Simplemente eche un vistazo a la clase HtmlHelper , por ejemplo. El método que traduce objetos a diccionarios es AnonymousObjectToHtmlAttributes . Sin embargo, es específico para MVC y devuelve un RouteValueDictionary .

Si quieres algo más genérico, prueba esto:

public static IDictionary<string,object> AnonymousObjectToDictionary(object obj) { return TypeDescriptor.GetProperties(obj) .OfType<PropertyDescriptor>() .ToDictionary( prop => prop.Name, prop => prop.GetValue(obj) ); }

Una ventaja interesante de esta implementación es que devuelve un diccionario vacío para objetos null .

Y aquí hay una versión genérica:

public static IDictionary<string,T> AnonymousObjectToDictionary<T>( object obj, Func<object,T> valueSelect ) { return TypeDescriptor.GetProperties(obj) .OfType<PropertyDescriptor>() .ToDictionary<PropertyDescriptor,string,T>( prop => prop.Name, prop => valueSelect(prop.GetValue(obj)) ); }


No puede declarar directamente un tipo de diccionario (existen kludges, pero solo para fines de entretenimiento y novedad), pero si sus datos provienen de un origen IEnumerable o IQueryable, puede obtener uno utilizando el operador LINQ ToDictionary y proyectándose la clave requerida y el valor (anotado de forma anónima) de los elementos de secuencia:

var intToAnon = sourceSequence.ToDictionary( e => e.Id, e => new { e.Column, e.Localized });


Puedes hacer una reflexión

public static class ObjectExtensions { /// <summary> /// Turn anonymous object to dictionary /// </summary> /// <param name="data"></param> /// <returns></returns> public static IDictionary<string, object> ToDictionary(this object data) { var attr = BindingFlags.Public | BindingFlags.Instance; var dict = new Dictionary<string, object>(); foreach (var property in data.GetType().GetProperties(attr)) { if (property.CanRead) { dict.Add(property.Name, property.GetValue(data, null)); } } return dict; } }