C# 将属性反序列化为预先存在的对象

C# 将属性反序列化为预先存在的对象,c#,serialization,C#,Serialization,是否可以使用任何标准序列化程序反序列化对象属性,而不创建新对象 问题是,所讨论的对象非常复杂(它们只能由特殊工厂创建,并且它们的类型在运行时动态生成),但它们有一些已知的属性,我想存储在外部文件中(最好是xml,但二进制也可以),然后(可能在应用程序重新启动后),我希望将存储的属性设置回我提供的对象 似乎所有的标准序列化程序只能为我生成一个新对象(它还需要一个公共的无参数构造函数),我必须从中手动分配所有属性。这与手动序列化没有太大区别,我希望避免手动序列化,因为一组序列化属性非常大,并且在项目

是否可以使用任何标准序列化程序反序列化对象属性,而不创建新对象

问题是,所讨论的对象非常复杂(它们只能由特殊工厂创建,并且它们的类型在运行时动态生成),但它们有一些已知的属性,我想存储在外部文件中(最好是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,以及处理子数据的所有复杂性等。老实说,简单地用一个方法来设置这些值并没有什么好处——在这一点上,您可以使用反射。