当您没有类的源代码时,是否可以对对象进行 .NET 二进制序列化?

2023-12-05

我在用BinaryFormatter在 C# 中对某些对象进行二进制序列化。但是,某些对象包含我通过 DLL 访问的类,并且没有源代码,因此我无法使用Serializable属性。有没有一种直接的方法来序列化它们?我有一个解决方法,其中包括上课NoSource并创建一个新类SerializableNoSource其构造函数采用NoSource对象并从中提取我需要的所有信息,但它很hacky。还有更好的选择吗?


你可以创建一个序列化代理.

想象一下,我们在引用的程序集中定义了一个我们无法控制的类,如下所示:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public DriversLicense License;
}


// An instance of this type will be part of the object graph and will need to be 
// serialized also.
public class DriversLicense
{
    public string Number { get; set; }
}

为了序列化该对象,您需要为对象图中的每种类型定义一个序列化代理。

要创建序列化代理,您只需创建一个实现以下功能的类型:ISerializationSurrogate界面:

public class PersonSurrogate : ISerializationSurrogate
{
    /// <summary>
    /// Manually add objects to the <see cref="SerializationInfo"/> store.
    /// </summary>
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
    {
        Person person = (Person) obj;
        info.AddValue("Name", person.Name);
        info.AddValue("Age", person.Age);
        info.AddValue("License", person.License);
    }

    /// <summary>
    /// Retrieves objects from the <see cref="SerializationInfo"/> store.
    /// </summary>
    /// <returns></returns>
    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
    {
        Person person = (Person)obj;
        person.Name = info.GetString("Name");
        person.Age = info.GetInt32("Age");
        person.License = (DriversLicense) info.GetValue("License", typeof(DriversLicense));
        return person;
    }
}

public class DriversLicenseSurrogate : ISerializationSurrogate
{
    /// <summary>
    /// Manually add objects to the <see cref="SerializationInfo"/> store.
    /// </summary>
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
    {
        DriversLicense license = (DriversLicense)obj;
        info.AddValue("Number", license.Number);
    }

    /// <summary>
    /// Retrieves objects from the <see cref="SerializationInfo"/> store.
    /// </summary>
    /// <returns></returns>
    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
    {
        DriversLicense license = (DriversLicense)obj;
        license.Number = info.GetString("Number");
        return license;
    }
}

那么你需要让你的IFormatter通过定义和初始化来了解代理SurrogateSelector并将其分配给您的IFormatter.

private static void SerializePerson(Person person)
{
    if (person == null)
        throw new ArgumentNullException("person");

    using (var memoryStream = new MemoryStream())
    {
        //Configure our surrogate selectors.
        var surrogateSelector = new SurrogateSelector();
        surrogateSelector.AddSurrogate(typeof (Person), new StreamingContext(StreamingContextStates.All),
                                       new PersonSurrogate());
        surrogateSelector.AddSurrogate(typeof (DriversLicense), new StreamingContext(StreamingContextStates.All),
                                       new DriversLicenseSurrogate());

        //Serialize the object
        IFormatter formatter = new BinaryFormatter();
        formatter.SurrogateSelector = surrogateSelector;
        formatter.Serialize(memoryStream, person);

        //Return to the beginning of the stream
        memoryStream.Seek(0, SeekOrigin.Begin);

        //Deserialize the object
        Person deserializedPerson = (Person) formatter.Deserialize(memoryStream);
    }
}

使用序列化代理绝不是简单的,并且当您尝试序列化的类型具有需要序列化的私有和受保护字段时,实际上可能会变得非常冗长。

但由于您已经手动序列化所需的值,我认为这不是问题。使用代理是处理此类场景的更统一的方式,应该会让您感觉更舒服。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当您没有类的源代码时,是否可以对对象进行 .NET 二进制序列化? 的相关文章

随机推荐

  • 根据 3 个变量的颜色 - 麦克斯韦三角形

    我有一个由三个变量 u v w 组成的模型 它们随时间和空间而变化 我对这三个变量的比率特别感兴趣 但我宁愿只使用一张图 而不是显示三张图 每张图对应一个变量 我的想法是使用麦克斯韦三角形 颜色三角形 参见http homepages ab
  • ASP.NET Intranet 站点要求提供凭据 - Windows 身份验证

    我在 ASP Net 中创建了我的第一个网站 并且正在尝试在我们工作的 Intranet 上启动并运行它 我现在几乎已经完成了所有事情 但我遇到了障碍 我需要使用 Windows 身份验证 我的团队的要求 因此我完成了设置网站的过程 我已配
  • 对同一对象调用两次 MustHaveHappened 失败

    给定以下被测类 以及关联的 DTO 类和接口 public class Foo private readonly IBar bar public Foo IBar bar bar bar public void DoStuff var dt
  • 如何在项目中包含多个log4j2.xml文件?

    我的项目由多个模块组成 每个模块都可以独立运行并有单独的log4j2 xml 假设 Project X 由三个模块组成 模块 A 有 log4j2 xml 包含 Loggers 和 Appenders 模块 B 有 log4j2 xml 模
  • .vimrc 来源不正确

    我的 vimrc 中有以下几行 colorscheme solarized 这显然设置了日晒配色方案 我实际的 vimrc 肯定比这个长 并且我还指定了更多 Solarized 选项 但是 我面临的问题可以使用这个最小的 vimrc 文件来
  • Linux中DMA如何处理memcpy

    我在程序中使用 memcpy 不幸的是 当我增加变量数量时 CPU 使用率会增加 就好像 memcpy 是通过使用 for 循环迭代来运行的 linux 中也有快速的 memcpy 函数吗 我应该使用补丁并编译内核吗 在某些架构中 CPU
  • Bootstrap 突然不适用于我的 React JS 项目

    突然 引导程序停止了我的项目的工作 我不知道为什么 这是我们的 package json name blankets version 0 1 0 private true dependencies amazon cognito identi
  • 数据卡和U盘或U盘的区别

    我有一张沃达丰数据卡 可以插入 USB 端口 我有 XP 和 Vista 操作系统 并且我正在使用WM DEVICECHANGEWindows 事件 了解 USB 插入和拔出 它对我来说工作得很好 但我无法区分数据卡插入和笔驱动器插入 是否
  • 为了迭代数组,我们应该使用 size_t 还是 ptrdiff_t?

    In this 安德烈 卡尔波夫 Andrey Karpov 的博客文章标题为 About size t and ptrdiff t 他举了一个例子 for ptrdiff t i 0 i lt n i a i 0 不过不知道对不对 好像应
  • 如何在 F# 中将字典“转换”为序列?

    如何将字典 转换 为序列以便可以按键值排序 let results new Dictionary results Add George 10 results Add Peter 5 results Add Jimmy 9 results A
  • Django 垃圾评论

    Django 的评论框架中的反垃圾邮件系统效果如何 你用过吗 它大约可以防止多少百分比的垃圾评论 您还采取其他措施来帮助防止使用 Django 评论框架的网站上出现垃圾评论吗 有一个 Python API 可以Askimet 这就是 Wor
  • 在C中递归创建并遍历二叉树

    我想创建一个二叉树并通过前序遍历来遍历它 并且我使用递归方法 这些代码可以编译但不能正确运行 我发现它可能无法完成CreateBitree 功能可以 但不知道问题出在哪里 include
  • 在 Android 上的 React-Native 中压缩 Base64 编码图像无法识别“数据”协议

    Issue 在 React Native 0 43 应用程序中 我们使用一个组件 该组件使用 SectionList 来渲染按天排序的照片 每个部分可以包含多个图像 照片是使用反应本机图像作物选择器库并上传到后端 或者在没有可用互联网连接的
  • 核心数据 - 无法在路径加载优化模型

    当我在装有 iOS 9 beta 5 的 iPhone 6 中通过 Xcode 6 运行应用程序时 我在控制台中收到了一些打印内容 CoreData 无法在路径 var mobile Containers Bundle Applicatio
  • 从 Android 设备调用 Web 服务

    我已经使用 python Flask 框架在本地编写了一个 Web 服务 该框架运行在localhost 5000 我通过编写从我的计算机浏览器成功运行此 Web 服务http localhost 5000 toi something 现在
  • 卸载注入的 DLL

    我有一个 DLL 我使用它注入到其他进程中SetWindowsHookEx 在 DLL 内部 我通过调用来增加模块的引用计数器GetModuleHandleEx这样我就可以控制模块何时卸载 此时 这两个 API 调用的模块引用计数 应该 为
  • 使用 PHP 使用 .pfx 证书签署 XML 文件

    我有一个 XML 文档 我想使用 PHP 使用 pfx 证书对其进行签名 我怎么能这样做呢 是否存在某些库或开源代码 或者文档的哪一部分可以帮助我 非常感谢您的帮助 请原谅我的英语不好 以下是使用 pfx 文件签署 xml 文件的最小示例
  • 让 EF 使用具有附加属性的 m:n 表 [重复]

    这个问题在这里已经有答案了 我在创建新应用程序时遇到了问题 该应用程序是关于在特定日期入职的新员工的 由于他们需要一些硬件 例如笔记本电脑 键盘等 我们希望对未来几天内即将到来的所有新员工进行概述 于是就有了以下几种Model Entry
  • 如何访问 VanillaJS 文件中的“this”上下文(Vue/Nuxt 实例)?

    我里面有一个函数 jsnuxt 2 项目中的文件 基本上我需要使用 nuxt 模块属性nuxt config像这样this nuxt options 在正常的函数内部 js file 例如 aNormalJsFile js if this
  • 当您没有类的源代码时,是否可以对对象进行 .NET 二进制序列化?

    我在用BinaryFormatter在 C 中对某些对象进行二进制序列化 但是 某些对象包含我通过 DLL 访问的类 并且没有源代码 因此我无法使用Serializable属性 有没有一种直接的方法来序列化它们 我有一个解决方法 其中包括上