Подтвердить что ты не робот

Есть ли простой способ преобразования свойств объекта в словарь <string, string>

У меня есть объект базы данных (строка), который имеет множество свойств (столбцов), которые сопоставляются для формирования полей (asp: textbox, asp: dropdownlist и т.д.). Я хотел бы преобразовать этот объект и свойства в карту словаря, чтобы упростить итерацию.

Пример:

Dictionary<string, string> FD = new Dictionary<string,string>();
FD["name"] = data.name;
FD["age"] = data.age;
FD["occupation"] = data.occupation;
FD["email"] = data.email;
..........

Как я могу сделать это легко, без ручного ввода всех различных 100 свойств?

Примечание: индексы словаря FD совпадают с именами столбцов базы данных.

4b9b3361

Ответ 1

Предполагая, что data является некоторым объектом и что вы хотите поместить его публичные свойства в словарь, вы можете попробовать:

Оригинал - здесь по историческим причинам (2012):

Dictionary<string, string> FD = (from x in data.GetType().GetProperties() select x)
    .ToDictionary (x => x.Name, x => (x.GetGetMethod().Invoke (data, null) == null ? "" : x.GetGetMethod().Invoke (data, null).ToString()));

Обновлено (2017):

Dictionary<string, string> dictionary = data.GetType().GetProperties()
    .ToDictionary(x => x.Name, x => x.GetValue(data)?.ToString() ?? "");

Ответ 2

Класс HtmlHelper позволяет преобразовать объект Anonymouns в RouteValueDictonary, и я полагаю, вы могли бы использовать .ToString() для каждого значения, чтобы получить реверсентацию строк:

 var linkAttributes = System.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes(linkHtmlAttributes);

Нижняя сторона - это часть ASP.NET MVC Framework. Используя .NET Reflector, код внутри метода выглядит следующим образом:

public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes)
{
   RouteValueDictionary dictionary = new RouteValueDictionary();
  if (htmlAttributes != null)
  {
     foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes))
     {
            dictionary.Add(descriptor.Name.Replace('_', '-'), descriptor.GetValue(htmlAttributes));
       }
 }
    return dictionary;
 }

Вы увидите, что этот код идентичен ответу, который дал Яхиа, и его ответ предоставляет строку Dictonary < string, string > . С отраженным кодом, который я вам предоставил, вы можете легко преобразовать RouteValueDictionary в Dictonary < string, string > но ответ Yahia - это один лайнер.

EDIT - я добавил код для того, что может быть методом для преобразования:

EDIT 2 - я добавил нулевую проверку кода и использовал String.Format для строкового значения

    public static Dictionary<string, string> ObjectToDictionary(object value)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        if (value != null)
        {
            foreach (System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(value))
            {
                if(descriptor != null && descriptor.Name != null)
                {
                     object propValue = descriptor.GetValue(value);
                     if(propValue != null)
                          dictionary.Add(descriptor.Name,String.Format("{0}",propValue));
            }
        }
        return dictionary;
    }

И перейти от Словаря к объекту, чтобы проверить http://automapper.org/, который был предложен в этом потоке Конвертировать словарь в анонимный объект

Ответ 3

var myDict = myObj.ToDictionary(); //returns all public fields & properties

.

public static class MyExtensions
{
    public static Dictionary<string, object> ToDictionary(this object myObj)
    {
        return myObj.GetType()
            .GetProperties()
            .Select(pi => new { Name = pi.Name, Value = pi.GetValue(myObj, null) })
            .Union( 
                myObj.GetType()
                .GetFields()
                .Select(fi => new { Name = fi.Name, Value = fi.GetValue(myObj) })
             )
            .ToDictionary(ks => ks.Name, vs => vs.Value);
    }
}

Ответ 4

Взгляните на System.ComponentModel.TypeDescriptor.GetProperties( ... ). Так работают обычные биты привязки данных. Он будет использовать отражение и возвращает вам набор дескрипторов свойств (которые вы можете использовать для получения значений). Вы можете настроить эти дескрипторы для performace, выполнив ICustomTypeDescriptor.