C# 将属性反序列化为预先存在的对象
是否可以使用任何标准序列化程序反序列化对象属性,而不创建新对象 问题是,所讨论的对象非常复杂(它们只能由特殊工厂创建,并且它们的类型在运行时动态生成),但它们有一些已知的属性,我想存储在外部文件中(最好是xml,但二进制也可以),然后(可能在应用程序重新启动后),我希望将存储的属性设置回我提供的对象 似乎所有的标准序列化程序只能为我生成一个新对象(它还需要一个公共的无参数构造函数),我必须从中手动分配所有属性。这与手动序列化没有太大区别,我希望避免手动序列化,因为一组序列化属性非常大,并且在项目生命周期中可能会更改几次。此时,我已经非常接近于编写自己的轻量级序列化程序,但也许有人可以建议一种更标准的方法来完成这些事情?有一个C# 将属性反序列化为预先存在的对象,c#,serialization,C#,Serialization,是否可以使用任何标准序列化程序反序列化对象属性,而不创建新对象 问题是,所讨论的对象非常复杂(它们只能由特殊工厂创建,并且它们的类型在运行时动态生成),但它们有一些已知的属性,我想存储在外部文件中(最好是xml,但二进制也可以),然后(可能在应用程序重新启动后),我希望将存储的属性设置回我提供的对象 似乎所有的标准序列化程序只能为我生成一个新对象(它还需要一个公共的无参数构造函数),我必须从中手动分配所有属性。这与手动序列化没有太大区别,我希望避免手动序列化,因为一组序列化属性非常大,并且在项目
序列化程序。Merge
方法可以让您反序列化到现有实例中。只写入流中找到的值(它不会擦除对象)
不是微软,但相当稳定
在此基础上进行扩展;获得处理所有常见场景的健壮序列化(我从痛苦的经历中知道)是一项艰巨的工作。我的建议肯定是尽可能重用现有代码。protobuf网络似乎提供了您所需要的一切;当前的二进制文件只要求您修饰类(非常类似于WCF中的
[DataContract]
,事实上它甚至支持[DataContract]
/[DataMember]
),但是,即使在POCO环境下也可以使用它,因此您可以将其用于您无法控制的类型。您可以实现自己灵活的“序列化程序”来处理此问题。反射为您提供了所需的一切。您可以使用该方法,它似乎正是为此任务而设计的。您可以使用类
你有一本教科书:
[Serializable]
class Book
{
public string Title { get; set; }
public string Author { get; set; }
// Constructor for setting new values.
public Book(string title, string author)
{
Title = title;
Author = author;
}
}
您可以按如下方式序列化它:
var book = new Book("Moby Dick", "Herman Melville");
string path = Path.GetTempFileName();
var bf = new BinaryFormatter();
using (var fs = new FileStream(path, FileMode.Create))
bf.Serialize(fs, book);
如果修改了对象:
// Edit object
book.Title = "Foo";
Console.WriteLine("{0}, {1}", book.Title, book.Author);
您可以使用以下代码还原它:
Book temp;
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
temp = (Book) bf.Deserialize(fs);
MemberInfo[] members = FormatterServices.GetSerializableMembers(typeof (Book));
FormatterServices.PopulateObjectMembers(book, members, FormatterServices.GetObjectData(temp, members));
// Object state is back
Console.WriteLine("{0}, {1}", book.Title, book.Author);
这不是在字段级别上工作,而不是在请求的属性级别上工作吗?@Lucero-它在字段和属性上都工作;这取决于你告诉它做什么。谢谢你提供了一个有趣的链接,但我不想让一个全新的第三方组件来完成这样一个相当简单的任务。另一个缺点是它不是xml。到那时,您将不得不解析流以将值放入
对象
s,并获得成员信息
s,以及处理子数据的所有复杂性等。老实说,简单地用一个方法来设置这些值并没有什么好处——在这一点上,您可以使用反射。