自定义一个结构体,使其序列化为 Int32

发布于 2024-11-27 01:28:18 字数 1216 浏览 1 评论 0原文

我使用二进制序列化保存数据。现在我已将程序中的一个字段从 Int32 更改为结构体。但我仍然想将该字段保存为 Int32 以向后兼容。我该怎么做?

背景信息 我的程序是从Delphi移植的并且使用了很多数组。问题是 Delphi 中的列表从 1 开始计数,当我现在用 C# 开发时,vilkort 使跟踪索引变得困难。所以我使用一个结构体来更容易地处理基于 1 的索引从 0 开始的数组,直到我纠正了整个程序。

代码

    public void Save()
    {
            using (var writer = File.Open(Path, FileMode.Create))
            {
                var serializer = new BinaryFormatter();
                serializer.Serialize(writer, _data);
            }
    }

    private void Load()
    {
        using (var reader = File.Open(Path, FileMode.Open))
        {
                var deserializer = new BinaryFormatter();
                _data = (Foo) deserializer.Deserialize(reader);
        }
    }

public struct Indexer
{
    //0-baserat index
    private int _index;

    public Indexer(int index)
    {
        _index = index;
    }

    static public implicit operator Indexer(int index)
    {
        return new Indexer(index);
    }

    static public implicit operator int(Indexer indexer)
    {
        return indexer._index;
    }

    public override string ToString()
    {
        return (_index + 1).ToString();
    }

    ...
  }

I save data using binary serialization. Now I have changed a field in the program from Int32 to a struct. But I still want to save the field as Int32 to be backward compatible. How do I do that?

background information
My program is ported from Delphi and uses a lot of arrays. The problem is that the lists in Delphi start counting from 1, vilkort has made it difficult to keep track of the indexes when I am now developing in C#.So I use a struct to make it easier to deal with the 1-based index of the 0-based arrays until I have corrected the whole program.

The code

    public void Save()
    {
            using (var writer = File.Open(Path, FileMode.Create))
            {
                var serializer = new BinaryFormatter();
                serializer.Serialize(writer, _data);
            }
    }

    private void Load()
    {
        using (var reader = File.Open(Path, FileMode.Open))
        {
                var deserializer = new BinaryFormatter();
                _data = (Foo) deserializer.Deserialize(reader);
        }
    }

public struct Indexer
{
    //0-baserat index
    private int _index;

    public Indexer(int index)
    {
        _index = index;
    }

    static public implicit operator Indexer(int index)
    {
        return new Indexer(index);
    }

    static public implicit operator int(Indexer indexer)
    {
        return indexer._index;
    }

    public override string ToString()
    {
        return (_index + 1).ToString();
    }

    ...
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

没︽人懂的悲伤 2024-12-04 01:28:19

您可以添加 Int32 类型的旧字段,并且还具有结构字段。使用 [OnDeserialized] 属性(和正确的参数)创建一个方法,并在某些情况下从 int 字段初始化 struct 字段,例如 int 字段非零并且反序列化后结构具有默认值,表明数据是从旧的格式。

private int intValue;                // Legacy field
private SomeStruct structValue;      // New field

[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
  if (intValue != 0)
  {
      // Old format, initialize struct with int value.
      structValue = new SomeStruct(intValue);
  }
}

这并不完全优雅,还有其他方法,但如果您不介意保留两个字段,这是更简单的方法之一。请注意,上面的代码假设零表示旧 int 字段的“缺失”值。

You can add a legacy field of Int32 type, and also have the struct field. Make a method with the [OnDeserialized] attribute (and the correct arguments) and initialize the struct field from the int field under some circumstances, for example that the int field is nonzero and the struct has default value after deserialization, indicating that the data is from the older format.

private int intValue;                // Legacy field
private SomeStruct structValue;      // New field

[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
  if (intValue != 0)
  {
      // Old format, initialize struct with int value.
      structValue = new SomeStruct(intValue);
  }
}

This is not exactly elegant and there are other ways, but if you don't mind keeping two fields this is one of the simpler ways. Note that the above code assumes that zero indicates a "missing" value for the old int field.

Hello爱情风 2024-12-04 01:28:19

我想唯一的方法是有两个类 - 一个是 struct,另一个是 int32。
然后,您可以在序列化后将其中一种转换为另一种。明确指出,不存在向后兼容性。

I guess the only way will be to have two classes - one with the struct and one with int32.
You could then convert one into the other after the serialzation. It is explicitly stated, that there is no backwards compatibility.

紫﹏色ふ单纯 2024-12-04 01:28:19
 int n = YourStruct.SomeIntVar;
 Marshal.WriteInt32(hBuffer, n);

我不确定这是否适合您的情况,因为这取决于您如何将数据序列化到档案中。如果您直接操作内存或共享内存(hBuffer)上的数据,上面的代码片段应该会有所帮助。

 int n = YourStruct.SomeIntVar;
 Marshal.WriteInt32(hBuffer, n);

I am not sure if this works for your case, as it depends on how you serialize your data into archives. In case you directly manipulate the data on memory or share memory (hBuffer), the above snippet should help.

夏雨凉 2024-12-04 01:28:19

ISerializerSurrogate

这将允许您控制序列化/反序列化过程。

ISerializerSurrogate

This will allow you control the serialization/deserialization process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文