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;
}
}