Un dizionario in cui il valore è un tipo anonimo in C #

È ansible in C # creare un System.Collections.Generic.Dictionary dove TKey è una class incondizionata e TValue – una class anonima con un numero di proprietà, ad esempio – il nome della colonna del database e il nome localizzato.

Qualcosa come questo:

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

Non è ansible dichiarare tale tipo di dizionario direttamente (ci sono dei kludges ma questi sono solo a scopo di intrattenimento e novità), ma se i tuoi dati provengono da una sorgente IEnumerable o IQueryable, puoi ottenerne uno usando l’operatore LINQ ToDictionary e proiettare all’esterno la chiave richiesta e il valore (anonimo tipizzato) dagli elementi della sequenza:

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

Come ha detto itowlson , non puoi dichiarare una tale bestia, ma puoi effettivamente crearne una:

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

Non è chiaro il motivo per cui in realtà vorresti usare un codice come questo.

Puoi fare un refection

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

Penso che ASP.NET MVC non sia uscito nel momento in cui è stata fatta questa domanda. Converte internamente oggetti anonimi in dizionari.

Basta dare un’occhiata alla class HtmlHelper , per esempio. Il metodo che traduce gli oggetti nei dizionari è AnonymousObjectToHtmlAttributes . È specifico per MVC e restituisce un RouteValueDictionary , tuttavia.

Se vuoi qualcosa di più generico, prova questo:

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

Uno degli interessanti vantaggi di questa implementazione è che restituisce un dizionario vuoto per oggetti null .

Ed ecco una versione generica:

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