C# 在.NET 4.5+;中分解/重新组合对象层次结构的最有效方法。NET标准1.0+;/。NET Core 1.0+; 脚本
我有一个用例,我需要将一个层次对象树分解成一组组成对象。稍后,我还需要C# 在.NET 4.5+;中分解/重新组合对象层次结构的最有效方法。NET标准1.0+;/。NET Core 1.0+; 脚本,c#,.net,serialization,reflection,.net-core,C#,.net,Serialization,Reflection,.net Core,我有一个用例,我需要将一个层次对象树分解成一组组成对象。稍后,我还需要将这些对象重新组合成其原始形式(或其一些变体) 目标 我的目标如下 确定分解/重新组合对象的最快和最处理器和/或内存效率方法。(此代码将处理数百万个对象,因此即使保存几个刻度也很有用。) 找到任何现有的库或示例,它们可能有助于此分解/重新编译场景,或者可以演示其他人是如何完成类似操作的 编制一份策略、方法和技术列表,用于分解对象层次结构(在.NET 4.5+,.NET核心)到其基本对象中,并将这些基本对象重新组合回层次结构(
将这些对象重新组合成其原始形式(或其一些变体)
目标
我的目标如下
- 确定
分解/重新组合对象的最快
和最处理器
和/或内存效率
方法。(此代码将处理数百万个对象,因此即使保存几个刻度也很有用。)
- 找到任何现有的
库
或示例
,它们可能有助于此分解/重新编译
场景,或者可以演示其他人是如何完成类似操作的
- 编制一份
策略
、方法
和技术
列表,用于分解对象层次结构
(在.NET 4.5+
,.NET核心
)到其基本对象中,并将这些基本对象重新组合回层次结构(注意:这里没有太多的想法、太多的技术或太多的例子。)
“Givens”/要求
- 此功能将在
.NET Core 1.x
及更高版本中实现。向后兼容.NET4.5+
将是一个加号
对象树的结构不一定事先知道。
- 分解组件
必须能够处理任何提供的对象树李>
对象层次结构
可能有很多层。
分解
将递归运行,直到到达对象树的最低级别。大多数对象(下面描述的除外)将分解
数组
和集合
可以选择保持完整,而不是分解
。这将因使用情况而异。我想说,通常,数组
,字典
,简单列表
(例如字符串列表
)不会被分解<代码>复杂列表
(例如,对象列表
可能会分解
)
重新编译期间
,可以将其他对象插入到对象层次结构中(或替换现有对象),以生成全新类型的对象- 自引用
类的任何潜在影响
- 其他潜在元素或对象类型的含义或影响
-来自.NET参考源XmlSerializer
-CoreFx
-NewtonsoftJson
-ZeroFormatter
-用于.NET核心-非常高效李>messagepackcsharp
Protobuf.net
类层次结构
,它表示我希望在我们将处理的对象层次结构中找到的元素类型
这些措施包括:
-(例如整数)属性ValueType
-属性字符串
-属性DateTime
-属性自定义类
-收藏字典
-集合列表
-字段数组
Guid
的Id
public class EntityBase
{
public EntityBase()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
}
演示层次结构中的根对象
类型为Person
。它包含类型为string
、int
和DateTime
的各种常规属性,就像在大多数类中一样。它还包含列表
和字典
集合类
,一个数组
,以及对单个自定义对象的引用
public class Person : EntityBase
{
public Person()
{
Phones = new List<Phone>();
Addresses = new List<Address>();
Passwords = new Dictionary<string, string>();
FavoriteFood = new FoodPreference();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public int Weight { get; set; }
public DateTime DateOfBirth { get; set; }
public FoodPreference FavoriteFood {get; set;}
public string[] Dogs = { "Shayna", "Sport" };
public Dictionary<string, string> Passwords { get; set; }
public ICollection<Phone> Phones { get; set; }
public ICollection<Address> Addresses { get; set; }
}
有一个邮政地址集合
public class Address : EntityBase
{
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
有一个自定义类
,其中包含了一些关于喜爱食物的详细信息
public class FoodPreference : EntityBase
{
public string FoodCategory { get; set; }
public string FoodName { get; set; }
}
这里是一个示例方法,它用虚拟数据
填充继承权
public static Person BuildPerson()
{
return new Person
{
FirstName = "Anthony",
LastName = "Gatlin",
Weight = 154, // I wish. :)
DateOfBirth = DateTime.Parse("01/01/1970"),
Phones = new List<Phone>
{
new Phone {PhoneNumber = "601-555-1212"},
new Phone {PhoneNumber = "601-555-1213"}
},
Addresses = new List<Address>
{
new Address {StreetAddress = "111 Country Rd", City = "Heidelberg", State = "MS", PostalCode = "39349"}
},
Passwords = new Dictionary<string, string>
{
{"google","googlepass" },
{"skype","skypepass" },
{"facebook","facebookpass" }
},
FavoriteFood = new FoodPreference { FoodCategory = "Baked Goods", FoodName = "Chocolate Cake" }
};
}
预期结果
一旦对象从对象层次结构中分解
,我将最终存储某种简单层次结构
,这将允许我重新组合对象
给定以下Id
guid
629ae27e-17aa-49ad-823a-2cd2ebf0cb66
//个人Id
0c516c4d-ff64-4b8d-bb44-b430aa8d3ce5
57bdfdcb-4232-40e4-aab8-4c6387029257
//电话号码1
b591afc3-6e91-4030-ad26-00beefceca43
//电话号码2 public static Person BuildPerson()
{
return new Person
{
FirstName = "Anthony",
LastName = "Gatlin",
Weight = 154, // I wish. :)
DateOfBirth = DateTime.Parse("01/01/1970"),
Phones = new List<Phone>
{
new Phone {PhoneNumber = "601-555-1212"},
new Phone {PhoneNumber = "601-555-1213"}
},
Addresses = new List<Address>
{
new Address {StreetAddress = "111 Country Rd", City = "Heidelberg", State = "MS", PostalCode = "39349"}
},
Passwords = new Dictionary<string, string>
{
{"google","googlepass" },
{"skype","skypepass" },
{"facebook","facebookpass" }
},
FavoriteFood = new FoodPreference { FoodCategory = "Baked Goods", FoodName = "Chocolate Cake" }
};
}
{
"Dogs": [
"Shayna",
"Sport"
],
"FirstName": "Anthony",
"LastName": "Gatlin",
"Weight": 154,
"DateOfBirth": "1970-01-01T00:00:00",
"FavoriteFood": {
"FoodCategory": "Baked Goods",
"FoodName": "Chocolate Cake",
"Id": "0c516c4d-ff64-4b8d-bb44-b430aa8d3ce5"
},
"Passwords": {
"google": "googlepass",
"skype": "skypepass",
"facebook": "facebookpass"
},
"Phones": [
{
"PhoneNumber": "601-555-1212",
"Id": "57bdfdcb-4232-40e4-aab8-4c6387029257"
},
{
"PhoneNumber": "601-555-1213",
"Id": "b591afc3-6e91-4030-ad26-00beefceca43"
}
],
"Addresses": [
{
"StreetAddress": "111 Country Rd",
"City": "Heidelberg",
"State": "MS",
"PostalCode": "39349",
"Id": "94cc5e37-db96-44b7-869a-818968d99ddd"
}
],
"Id": "629ae27e-17aa-49ad-823a-2cd2ebf0cb66"
}
{
"Person":{
"Id":"629ae27e-17aa-49ad-823a-2cd2ebf0cb66",
"FavoriteFood":{
"Id":"0c516c4d-ff64-4b8d-bb44-b430aa8d3ce5"
},
"Phone":[
{
"Id":"57bdfdcb-4232-40e4-aab8-4c6387029257"
},
{
"Id":"b591afc3-6e91-4030-ad26-00beefceca43"
}
],
"Address":[
{
"Id":"94cc5e37-db96-44b7-869a-818968d99ddd"
}
]
}
}