在日常开发中,我们经常遇到将对象的属性扁平化的需求,特别是当我们需要序列化对象或者与不支持嵌套结构的接口交互时。这篇文章将介绍如何在 C# 中将一个包含多个子类的类的属性扁平化。通过几个完整、详细的例子,你将学会如何实现这一功能。
属性扁平化(Flattening Attributes)是指将一个具有嵌套结构的对象转换为单一层次结构的操作。这个过程通常涉及递归地访问嵌套对象的属性,并将它们拉平到根对象的层次中。
假设我们有一个 Person
类,其中包含一个 Address
子类。我们希望将 Person
的属性,以及 Address
中的属性都提取到一个巩固的平面结构中。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Address Address { get; set; }
}
public class FlatObject
{
public static IDictionary<string, object> Flatten(object source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
var result = new Dictionary<string, object>();
Type type = source.GetType();
foreach (PropertyInfo property in type.GetProperties())
{
object value = property.GetValue(source);
if (value != null && !IsSimpleType(property.PropertyType))
{
var nestedProperties = Flatten(value);
foreach (var nestedProperty in nestedProperties)
{
result[$"{property.Name}.{nestedProperty.Key}"] = nestedProperty.Value;
}
}
else
{
result[property.Name] = value;
}
}
return result;
}
private static bool IsSimpleType(Type type)
{
return type.IsPrimitive || type.IsEnum || type == typeof(string);
}
}
class Program
{
static void Main()
{
Person person = new Person
{
Name = "John Doe",
Age = 30,
Address = new Address
{
Street = "123 Main St",
City = "Anytown"
}
};
IDictionary<string, object> flatPerson = FlatObject.Flatten(person);
foreach (var property in flatPerson)
{
Console.WriteLine($"{property.Key}: {property.Value}");
}
}
}
为了说明更复杂的情况,让我们扩展 Person
类,在其中添加对另一个类 Company
的引用。
C#static void Main()
{
Person person = new Person
{
Name = "张三",
Age = 30,
Address = new Address
{
Street = "中山路123号",
City = "北京"
},
Company = new Company
{
Name = "科技有限公司",
Address = new Address
{
Street = "科技大道456号",
City = "上海"
}
}
};
IDictionary<string, object> flatPerson = FlatObject.Flatten(person);
foreach (var property in flatPerson)
{
Console.WriteLine($"{property.Key}: {property.Value}");
}
}
通过这两个例子,我们展示了如何将复杂对象的属性扁平化为一个字典结构。这里使用递归的方法,遍历每个属性,若属性还是一个复杂对象,则继续递归深入,直至提取出所有简单属性,再将结果组合到一起。
这种技术对于处理复杂数据结构,特别是与 RESTful API、JSON 格式化、日志记录等场景非常有用。希望这篇文章能够帮助你在实际应用中更好地管理对象的属性扁平化操作。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!