Tôi đã tìm thấy một cách rõ ràng để đạt được những gì bạn đang tìm kiếm mà không phá vỡ thiết kế của bạn.
Sử dụng phương pháp này sẽ đảm bảo rằng hàm tạo của bạn sẽ được gọi và trường chỉ đọc của bạn được đặt chính xác.
Những gì bạn cần là thực sự tuần tự hóa và deserialize [DataMember]
các trường được đánh dấu từ lớp DataModel.
Điều đó sẽ ngăn chặn bất kỳ hành vi ngoài ý muốn nào xảy ra khi biết rằng DataContractSerializer không gọi hàm tạo khi deserializing.
namespace MyApp.DataModel
{
//It is not mandatory to specify the DataContract since a default one will be
//provided on recent version of .Net, however it is a good practice to do so.
[DataContract(Name = "MyClassDataModel", Namespace = "MyApp.DataModel")]
public class MyClassDataModel
{
[DataMember]
public bool DataMemberExample{ get; set; }
}
}
Để deserializing và serializing bây giờ bạn có thể sử dụng lớp này để giữ giá trị của bạn.
Khi tải, bạn có thể tạo một đối tượng mô hình dữ liệu mới và chuyển nó tới lớp của bạn cần phải có hàm tạo của nó.
public MyObjectThatNeedToBeConstructed LoadData(){
// ...
// get your reader (Stream) from the file system or wherever it's located
var deserializer = new DataContractSerializer(typeof(MyClassDataModel));
var storedModel = (MyClassDataModel)deserializer.ReadObject(reader);
return new MyObjectThatNeedToBeConstructed(storedModel);
}
Khi lưu, bạn có thể trích xuất dữ liệu bắt buộc từ lớp có chứa trường ReadOnly.
public void SaveData(MyObjectThatNeedToBeConstructed myObject){
// ...
// get your writer (Stream) from memory or wherever it's located
var serializer = new DataContractSerializer(typeof(MyClassDataModel));
var dataModel = new MyClassDataModel{ DataMemberExample = myObject.DataMember};
serializer.WriteObject(writer, dataModel);
}
Tất nhiên, bạn sẽ phải thêm quá tải vào hàm tạo và bạn có thể phải chỉnh sửa ví dụ một chút, nhưng tôi nghĩ bạn có ảnh.
Tại sao bạn không thử? – svick
@svick: Tôi không thể nghĩ ra bất kỳ cơ chế nào để thực hiện việc gây quỹ. DataContractSerializer sử dụng 'FormatterServices.GetUninitializedObject' để" xây dựng "một đối tượng rỗng và không gọi một hàm tạo hoặc khởi tạo trường khởi tạo. Theo như tôi hiểu, một trường 'readonly' chỉ có thể được khởi tạo theo một trong hai cách đó (nhưng hy vọng có một cách khác mà tôi không quen thuộc). –
Ồ, tôi nghĩ bạn muốn deserialize lĩnh vực này.Tôi có hiểu bạn đúng không, ví dụ bạn muốn đặt trường thành một số giá trị mặc định, không đến từ dữ liệu được tuần tự hóa? – svick