我需要de / serialize对象。但是,有时我需要以某种方式序列化它们,有时则以其他方式序列化它们。
示例:
public interface I : ISerializable {
String X { get; set; }
String Y { get; set; }
}
public class A : I
{
String X {...}
String Y {...}
String MyZ { ... }
}
public class B : I
{
String X {...}
String Y {...}
String MyS { ... }
}
有时我需要仅使用A a
字段序列化B b
或X
对象,有时我只需要序列化Y
字段。
请知道这是一个小例子。场景中真正存在的是我只想用基本信息保存对象,有时我需要保存其他字段。
它类似于应用序列化模板。 有什么想法吗?
修改 而不是:
var f = new BinaryFormatter();
f.Context = new StreamingContext(StreamingContextStates.All, new []{ "X", "Y" });
使用:
var f = new BinaryFormatter();
f.Context = new StreamingContext(StreamingContextStates.All, TemplatesEnum.Template1);
因此,每个对象都可以自行承担,以便根据TemplatesEnum
值自行序列化。
答案 0 :(得分:1)
一种解决方案是利用ISerializable
实现StreamingContext
:
public enum TemplatesEnum
{
Template1,
Template2,
}
[Serializable]
public class A : I
{
public String X { get; set; }
public String Y { get; set; }
public String MyZ { get; set; }
public A() {}
// Special ctor for deserialization
public A(SerializationInfo info, StreamingContext context)
{
// Ignore context while deserializing.
foreach (SerializationEntry entry in info)
{
switch (entry.Name)
{
case "X":
X = (string)entry.Value;
break;
case "Y":
Y = (string)entry.Value;
break;
case "MyZ":
MyZ = (string)entry.Value;
break;
}
}
}
// ISerializable implementation
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
TemplatesEnum templ = (TemplatesEnum)context.Context;
// Determin which properties should be serialized depending on the context.
switch(templ)
{
case TemplatesEnum.Template1:
info.AddValue("X", X);
break;
case TemplatesEnum.Template2:
info.AddValue("X", X);
info.AddValue("Y", Y);
break;
}
}
}
(仅供参考:nameof(X)
优于C#6之后的文字"X"
。)
然后在序列化时将TemplatesEnum参数设置为IFormatter.Context
:
class Program
{
static void Main(string[] args)
{
A obj = new A() { X = "foo", Y = "bar", MyZ = "baz" };
var f = new BinaryFormatter();
// Serialize depending on a TemplateEnum param.
f.Context = new StreamingContext(StreamingContextStates.All, TemplatesEnum.Template1);
using (var stm = new FileStream("somefile.bin", FileMode.Create))
{
f.Serialize(stm, obj);
}
// Deserialize
using (var stm = new FileStream("somefile.bin", FileMode.Open))
{
A des = f.Deserialize(stm) as A;
}
}
}
答案 1 :(得分:0)
将对象序列化为文件的一种方法是使用BinaryFormatter类。您应该在类中包含属性[Serializable()]。如果您不想保留班级的特定字段,也可以使用[NonSerialized]属性。您还可以使用OnSerialized属性控制序列化过程,以及您在下面的示例中看到的另一个属性。您可以使用多个Formatter,这取决于您希望如何将数据保存为xml格式,json格式或具有特定格式的文件。
[Serializable]
public class MyObject
{
public string n1;
[NonSerialized] public int n2;
public String str;
[OnSerializing()]
internal void OnSerializingMethod(StreamingContext context)
{
n1= "This value went into the data file during serialization.";
}
[OnSerialized()]
internal void OnSerializedMethod(StreamingContext context)
{
n1 = "This value was reset after serialization.";
}
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context)
{
n1 = "This value was set during deserialization";
}
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
n1 = "This value was set after deserialization.";
}
}
var obj = new MyObject();
// Open a file and serialize the object into binary format.
Stream stream = File.Open("DataFile.txt", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
// Deserialize the object from the data file.
obj = (TestSimpleObject)formatter.Deserialize(stream);