De /序列化模板

时间:2016-06-07 14:23:48

标签: c# serialization

我需要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 bX对象,有时我只需要序列化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值自行序列化。

2 个答案:

答案 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);