gpt4 book ai didi

c# - 无注释的protobuf-net序列化

转载 作者:IT王子 更新时间:2023-10-29 04:47:49 26 4
gpt4 key购买 nike

我看了this回答,我处于不需要保持向后兼容性的情况,我必须有一个解决方案,而不必用 protobuf-net 所需的属性装饰几十个类。所以我尝试使用 RuntimeTypeModel.Default.InferTagFromNameDefault = true; 但我可能没有正确使用它,因为 Serializer.Serialize 调用仍然抛出异常要求契约(Contract)。这是我的快速测试,我做错了什么?

public enum CompanyTypes
{
None, Small, Big, Enterprise, Startup
}

public class BaseUser
{
public string SSN { get; set; }
}

public class User : BaseUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public DateTime BirthDate { get; set; }
public List<string> Friends { get; set; }
public Company Company { get; set; }
}

public class Company
{
public string Name { get; set; }
public string Address { get; set; }
public CompanyTypes Type { get; set; }
public List<Product> Products { get; set; }
}

public class Product
{
public string Name { get; set; }
public string Sku { get; set; }
}

[TestClass]
public class SerializationTest
{
[TestMethod]
public void SerializeDeserializeTest()
{
var user = new User
{
Age = 10,
BirthDate = DateTime.Now.AddYears(-10),
FirstName = "Test First",
LastName = "Test Last",
Friends = new List<string> { "Bob", "John" },
Company = new Company
{
Name = "Test Company",
Address = "Timbuktu",
Type = CompanyTypes.Startup,
Products = new List<Product>
{
new Product{Name="Nerf Rocket", Sku="12324AC"},
new Product{Name="Nerf Dart", Sku="DHSN123"}
}
}
};

RuntimeTypeModel.Default.InferTagFromNameDefault = true;
using (var memoryStream = new MemoryStream())
{
Serializer.Serialize(memoryStream, user);
var serialized = Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
}
}
}

最佳答案

InferTagFromName(它是双胞胎,InferTagFromNameDefault)仅在需要为成员解析标签编号时才伸出手;它们不会影响哪些成员需要序列化(因此目前对此的答案是:无,即使系统知道它们)。您可能选择的选项是ImplicitFields,但它目前仅可用作[ProtoContract(...)] 标记。如果您不介意一个注释,一个实用的修复可能是:

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]

关于 UserCompanyProduct,对于 BaseUser 来说有点复杂(因为继承):

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic, ImplicitFirstTag = 10)]
[ProtoInclude(1, typeof(User))]

请注意,我们不必为每个成员添加大量注释。如果你真的真的反属性,那么也可以通过代码配置整个模型,via:

RuntimeTypeModel.Default.Add(typeof(Product), false).Add("Name", "Sku");
RuntimeTypeModel.Default.Add(typeof(Company), false).Add("Name", "Address",
"Type", "Products");
RuntimeTypeModel.Default.Add(typeof(User), false).Add("FirstName", "LastName",
"Age", "BirthDate", "Friends", "Company");
RuntimeTypeModel.Default.Add(typeof(BaseUser), false).Add(10, "SSN")
.AddSubType(1, typeof(User));

关于c# - 无注释的protobuf-net序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12308196/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com