Как преобразовать класс в словарь <строка, строка>?

c# asp.net dictionary

52723 просмотра

6 ответа

1418 Репутация автора

Теперь я снова объясняю одну из моих страстей в отношении словаря! Этот вопрос всплыл в моем уме из ответа на мой предыдущий вопрос !!

Теперь актуальный вопрос: могу ли я преобразовать класс в словарь?

В словаре я хочу, чтобы свойства моего класса были KEY, а значение конкретного свойства - VALUE.

Предположим, мой класс

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

Теперь предположим, что мои данные

city = Delhi
state = Delhi
country = India

Теперь вы можете легко понять мою точку зрения!

Я хочу сделать словарь! Этот словарь должен быть как

Dictionary<string,string> dix = new Dictionary<string,string> ();
dix.add("property_name", "property_value");

Я могу получить значение! Но как я могу получить имена свойств ( не значения )?

Что я должен кодировать, чтобы создать его динамически! Это должно работать для каждого класса, который я хочу?

Вы можете понять этот вопрос как

Как я могу получить список свойств из определенного класса?

Автор: Chintan Источник Размещён: 09.02.2012 11:57

Ответы (6)


146 плюса

51692 Репутация автора

Решение

Это рецепт: 1 отражение, 1 LINQ-to-Objects!

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

С тех пор как я опубликовал этот ответ, я проверил, что многие нашли его полезным. Я приглашаю всех, кто ищет это простое решение, проверить другой вопрос и ответ, в котором я обобщил его в метод расширения: отображение объекта в словарь и наоборот .

Автор: Matías Fidemraizer Размещён: 09.02.2012 12:03

19 плюса

2233 Репутация автора

Вот пример с отражением без 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();
Автор: Bruno Costa Размещён: 09.02.2012 12:11

0 плюса

516 Репутация автора

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"];
}
Автор: Jon Размещён: 22.05.2017 06:13

0 плюса

1271 Репутация автора

Дайте это попробовать.

    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;
    }
Автор: joelc Размещён: 22.05.2017 06:17

2 плюса

81 Репутация автора

Я хотел бы добавить альтернативу рефлексии, используя JToken. Вам нужно будет проверить разницу в тестах, чтобы увидеть, какая из них имеет лучшую производительность.

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

Обратите внимание, что этот метод лучше всего подходит для плоской структуры классов.

Автор: FishFingers Размещён: 22.08.2017 01:20

0 плюса

127 Репутация автора

Просто подарок кому-то нужен только простой и плоский, Dictionary<String,String> не требующий иерархии или десериализации обратно к объекту, как я 🌳

    private static readonly IDictionary<string, string> SPECIAL_FILTER_DICT = new Dictionary<string, string>
    {
        { nameof(YourEntityClass.ComplexAndCostProperty), "Some display text instead"},
        { nameof(YourEntityClass.Base64Image), ""},
        //...
    };


    public static IDictionary<string, string> AsDictionary(this object source, BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
    {
        if (source == null)
            return new Dictionary<string, string> {
                {"",""}
            };

        return source.GetType().GetProperties(bindingAttr).ToDictionary
        (
            propInfo => propInfo.Name,
            propInfo => propInfo.GetValue(source, null).GetSafeStringValue(propInfo.Name)
        );
    }


    public static String GetSafeStringValue(this object obj, String fieldName)
    {
        if (obj == null)
            return "";

        if (obj is DateTime)
            return GetStringValue((DateTime)obj);

        // More specical convert...

        if (SPECIAL_FILTER_DICT.ContainsKey(fieldName))
            return SPECIAL_FILTER_DICT[fieldName];

        // Override ToString() method if needs
        return obj.ToString();
    }


    private static String GetStringValue(DateTime dateTime)
    {
        return dateTime.ToString("YOUR DATETIME FORMAT");
    }
Автор: Nguyen Minh Hien Размещён: 11.09.2019 03:09
32x32