【问题标题】:How to pass custom data to deserialization function如何将自定义数据传递给反序列化函数
【发布时间】:2011-12-01 15:03:38
【问题描述】:

我正在做一些 C# IO 工作,我想从几个类中导入/导出数据。 看了一会,好像序列化和我想要的很接近。

但是,有一个问题。我有一个 XML 文件,它描述了某个类的成员(我将其称为 ValueWithId),这些成员聚集在一个类中,我将为此问题称为 CollectionOfValuesWithId。

ValueWithId 是一个包含一个名为ShortName 的string 成员的类,该成员是唯一的。每个ValueWithId 只有一个ShortName,所有ValueWithId 都有一个非空ShortName。 CollectionOfValuesWithId 包含一个函数,用于查找具有给定 ShortName 的 ValueWithId。

序列化时,我确实不想在输出文件中存储ValueWithId 或CollectionOfValuesWithId。相反,我只想将ShortName 存储在文件中。 到目前为止,一切都很好。我只需要使用SerializationInfo.AddValue("ValueWithId", MyValueWIthId.ShortName)。

问题来自反序列化。一些谷歌搜索表明,要从文件中读取数据,可以这样做:

public SomeClassThatUsesValueWithId(SerializationInfo info, StreamingContext ctxt)
{
    string name = (string)info.GetValue("ValueWithId", typeof(string));
}

但是,字符串不足以恢复ValueWithId 实例。我还需要CollectionOfValuesWithId。我想要这样的东西:

public SomeClassThatUsesValueWithId(SerializationInfo info,
   StreamingContext ctxt, CollectionOfValuesWithId extraParameter)

换句话说,我需要将额外的数据传递给反序列化构造函数。有谁知道这样做的任何方法或任何替代方法?

【问题讨论】:

  • 你能展示你的班级和预期的 xml 吗?
  • @L.B 我将 XML 用于ValueWithId,但序列化本身将来自/到二进制,而不是 XML。我真的不关心生成的文件,我只是不希望ValueWithIds 在那里结束。

标签: c# .net serialization deserialization


【解决方案1】:

我想通了。执行此操作的重要类是StreamingContext。 这个类方便地有一个名为Context的属性(可以在构造函数参数additional中设置。

来自MSDN:

附加
类型:System.Object
与 流上下文。此信息可用于任何对象 实现 ISerializable 或任何序列化代理。大多数用户都这样做 不需要设置这个参数。

所以这里有一些关于如何做到这一点的示例代码(在 Mono 上测试,但我认为它应该在 Windows 上工作):

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class ValueWithId
{
    public string ShortName;
    public string ActualValue;

    public ValueWithId(string shortName, string actualValue)
    {
        ShortName = shortName;
        ActualValue = actualValue;
    }

    public override string ToString()
    {
        return ShortName + "->" + ActualValue;
    }
}

public class CollectionOfValuesWithId
{
    private IList<ValueWithId> Values = new List<ValueWithId>();

    public void AddValue(ValueWithId val)
    {
        Values.Add(val);
    }

    public ValueWithId GetValueFromId(string id)
    {
        foreach (var value in Values)
            if (value.ShortName == id)
                return value;
        return null;
    }
}

[Serializable]
public class SomeClassThatUsesValueWithId : ISerializable
{
    public ValueWithId Val;

    public SomeClassThatUsesValueWithId(ValueWithId val)
    {
        Val = val;
    }

    public SomeClassThatUsesValueWithId(SerializationInfo info, StreamingContext ctxt)
    {
        string valId = (string)info.GetString("Val");
        CollectionOfValuesWithId col = ctxt.Context as CollectionOfValuesWithId;
        if (col != null)
            Val = col.GetValueFromId(valId);
    }

    public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
    {
        //Store Val.ShortName instead of Val because we don't want to store the entire object
        info.AddValue("Val", Val.ShortName);
    }

    public override string ToString()
    {
        return "Content="+Val;
    }
}

class MainClass
{
    public static void Main(string[] args)
    {
        CollectionOfValuesWithId col = new CollectionOfValuesWithId();
        col.AddValue(new ValueWithId("foo", "bar"));

        SomeClassThatUsesValueWithId sc = new SomeClassThatUsesValueWithId(col.GetValueFromId("foo"));

        BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File, col));

        using (var stream = new FileStream("foo", FileMode.Create))
        {
            bf.Serialize(stream, sc);
        }

        col.GetValueFromId("foo").ActualValue = "new value";

        using (var stream2 = new FileStream("foo", FileMode.Open))
        {
            Console.WriteLine(bf.Deserialize(stream2));
        }
    }
}

我得到的输出是:

Content=foo->new value

这正是我想要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-25
    • 2016-03-24
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 2014-11-24
    • 2021-06-09
    相关资源
    最近更新 更多