如何将类转换为字典<字符串,字符串>

本文关键字:字符串 字典 转换 | 更新日期: 2023-09-27 18:23:49

我可以将类转换为字典<字符串,字符串>吗?

在字典中,我希望我的类属性作为,特定属性的值作为

假设我的类是

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

我可以得到价值!但是如何获取属性名称(不是值(?

我应该编写什么代码来创建动态?这应该适用于我想要的每个课程。

您可以将此问题理解为:

如何从特定类获取属性列表?

现在我再次解释我对字典的渴望之一!这个问题从我上一个问题的答案中突然出现在我的脑海中!!

如何将类转换为字典<字符串,字符串>

这是配方:1 个反射,1 个 LINQ 到对象!

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

自从我发表这个答案以来,我已经检查了很多人发现它很有用。我邀请所有寻找这个简单解决方案的人检查另一个问答,我将其推广为扩展方法:将对象映射到字典,反之亦然

下面是一个没有 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();
public static Dictionary<string, object> ToDictionary(object model)
    {
        var serializedModel = JsonModelSerializer.Serialize(model);
        return JsonModelSerializer.Deserialize<Dictionary<string, object>>(serializedModel);
    }

我已经使用了上面的代码。尽可能简化,它可以在没有反射的情况下工作,模型可以嵌套并且仍然可以工作。(如果您使用的是 Newtonsoft,请将您的代码更改为不使用 Newtonsoft Json.net(

我想使用 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()));

请注意,此方法最适合平面类结构。

试一试。

这使用反射来检索对象类型,然后检索所提供对象的所有属性(PropertyInfo prop in obj.GetType().GetProperties(),请参阅 https://learn.microsoft.com/en-us/dotnet/api/system.type.getproperties?view=netcore-3.1(。 然后,它将属性名称添加为字典中的键,如果存在值,则添加值,否则添加 null。

    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);
            }
            else
            {
                ret.Add(propName, null);
            }
        }
        return ret;
    }
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"];
}

只是送给某人的礼物只需要一个简单而扁平的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");
    }

我希望这个扩展对某人有用。

public static class Ext {
    public static Dictionary<string, object> ToDict<T>(this T target)
        => target is null
            ? new Dictionary<string, object>()
            : typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)
                        .ToDictionary(
                            x => x.Name,
                            x => x.GetValue(target)
                        );
}
public static Dictionary<string, string> ObjectToDictionary(object obj)
{
    return Newtonsoft.Json.Linq.JObject.FromObject(obj).ToObject<Dictionary<string, string>>();
}