在C#开发中,我们经常需要将Plain Old CLR Object (POCO)转换为Dictionary<string, object>
。这种需求在与第三方API交互、序列化数据、动态数据处理等场景中尤为常见。本文将深入探讨五种不同的转换方法,分析它们的特点、适用场景,并提供详细的代码示例和性能比较。
C#using System;
using System.Reflection;
namespace AppPOCO
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var person = new Person { Name = "Alice", Age = 30 };
var dict = ConvertToDict(person);
Console.WriteLine(dict["Name"]);
Console.WriteLine(dict["Age"]);
Console.ReadLine();
}
public static Dictionary<string, object> ConvertToDict(object obj)
{
return obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.ToDictionary(prop => prop.Name, prop => prop.GetValue(obj));
}
}
}
C#using System;
using System.Reflection;
namespace AppPOCO
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var person = new Person { Name = "Alice", Age = 30 };
var filteredDict = ConvertToDictFiltered(person, prop => prop.PropertyType == typeof(string));
Console.WriteLine(filteredDict["Name"]);
Console.ReadLine();
}
public static Dictionary<string, object> ConvertToDictFiltered(object obj, Func<PropertyInfo, bool> filter)
{
return obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(filter)
.ToDictionary(prop => prop.Name, prop => prop.GetValue(obj));
}
}
}
C#using System;
using System.Net;
using System.Reflection;
using Newtonsoft.Json;
using static AppPOCO.Person;
namespace AppPOCO
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
public Address address { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var complexPerson = new Person
{
Name = "Bob",
Age = 35,
address = new Address { Street = "123 Main St", City = "Anytown" }
};
var dict = ConvertToDictNewtonsoft(complexPerson);
foreach (var item in dict)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
Console.ReadLine();
}
public static Dictionary<string, object> ConvertToDictNewtonsoft(object obj)
{
var json = JsonConvert.SerializeObject(obj);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
}
}
}
C#using System;
using System.Net;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using static AppPOCO.Person;
namespace AppPOCO
{
public enum Gender { Male, Female }
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
public Address address { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var person = new Person { Name = "Charlie", Gender = Gender.Male };
var dict = ConvertToDictNewtonsoftCustom(person);
Console.WriteLine(JsonConvert.SerializeObject(dict));
Console.ReadLine();
}
public static Dictionary<string, object> ConvertToDictNewtonsoftCustom(object obj)
{
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
Converters = new List<JsonConverter> { new StringEnumConverter() }
};
var json = JsonConvert.SerializeObject(obj, settings);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(json, settings);
}
}
}
C#using System;
using System.Net;
using System.Reflection;
using System.Text.Json;
namespace AppPOCO
{
public enum Gender { Male, Female }
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
public Address address { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var person = new Person { Name = "David", Age = 40 };
var dict = ConvertToDictSystemTextJson(person);
Console.WriteLine(dict["Name"]);
Console.WriteLine(dict["Age"]);
Console.ReadLine();
}
public static Dictionary<string, object> ConvertToDictSystemTextJson(object obj)
{
var json = JsonSerializer.Serialize(obj);
return JsonSerializer.Deserialize<Dictionary<string, object>>(json);
}
}
}
C#public static Dictionary<string, object> ConvertToDictSystemTextJsonCustom(object obj)
{
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
var json = JsonSerializer.Serialize(obj, options);
return JsonSerializer.Deserialize<Dictionary<string, object>>(json, options);
}
C#using System;
using System.Net;
using System.Reflection;
using System.Text.Json;
namespace AppPOCO
{
public enum Gender { Male, Female }
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
public Address address { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var person = new Person { Name = "Frank", Age = 0 };
var dict = ConvertToDictLinq(person);
Console.WriteLine(JsonSerializer.Serialize(dict));
Console.ReadLine();
}
public static Dictionary<string, object> ConvertToDictLinq(object obj)
{
return obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.ToDictionary(
prop => prop.Name,
prop => prop.GetValue(obj) ?? "N/A"
);
}
}
}
C#using System;
using System.Net;
using System.Reflection;
using System.Text.Json;
namespace AppPOCO
{
public enum Gender { Male, Female }
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
public Address address { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var person = new Person { Name = "Grace", Age = 50 };
var dict = ConvertToDictLinqCustom(person);
Console.WriteLine(JsonSerializer.Serialize(dict));
Console.ReadLine();
}
public static Dictionary<string, object> ConvertToDictLinqCustom(object obj)
{
return obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.ToDictionary(
prop => prop.Name.ToLower(),
prop => prop.PropertyType == typeof(string)
? prop.GetValue(obj)?.ToString().ToUpper()
: prop.GetValue(obj)
);
}
}
}
C#using System;
using System.Dynamic;
using System.Net;
using System.Reflection;
using System.Text.Json;
namespace AppPOCO
{
public enum Gender { Male, Female }
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
public Address address { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var person = new Person { Name = "Henry", Age = 45 };
dynamic expandoDict = ConvertToExpandoObject(person);
Console.WriteLine(expandoDict.Name); // 输出: Henry
expandoDict.Job = "Developer"; // 动态添加属性
Console.WriteLine(JsonSerializer.Serialize(expandoDict));
Console.ReadLine();
}
public static dynamic ConvertToExpandoObject(object obj)
{
var expando = new ExpandoObject();
var expandoDic = (IDictionary<string, object>)expando;
foreach (var prop in obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
expandoDic.Add(prop.Name, prop.GetValue(obj));
}
return expando;
}
}
}
C#using System;
using System.Dynamic;
using System.Net;
using System.Reflection;
using System.Text.Json;
namespace AppPOCO
{
public enum Gender { Male, Female }
public class Person
{
public string Email { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
public Address address { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 使用示例
var person = new Person { Name = "Ivy", Age = 0, Email = "ivy@example.com" };
dynamic filteredExpando = ConvertToExpandoObjectFiltered(person, prop => prop.GetValue(person) != null && !prop.GetValue(person).Equals(0));
Console.WriteLine(JsonSerializer.Serialize(filteredExpando));
Console.ReadLine();
}
public static dynamic ConvertToExpandoObjectFiltered(object obj, Func<PropertyInfo, bool> filter)
{
var expando = new ExpandoObject();
var expandoDic = (IDictionary<string, object>)expando;
obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(filter)
.ToList()
.ForEach(prop => expandoDic.Add(prop.Name, prop.GetValue(obj)));
return expando;
}
}
}
根据文章中提供的基准测试结果,我们可以得出以下结论:
选择合适的POCO到Dictionary的转换方法取决于多个因素:
在实际应用中,建议根据具体场景选择最合适的方法,并进行必要的性能测试和优化。对于大多数简单场景,反射或LINQ方法可能是最佳选择;而对于复杂对象或需要特殊处理的情况,JSON序列化方法或ExpandoObject可能更为合适。
无论选择哪种方法,都要注意处理潜在的异常情况,如空值、循环引用等,以确保代码的健壮性和可靠性。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!