代码之家  ›  专栏  ›  技术社区  ›  Michael

保存C类定义

  •  1
  • Michael  · 技术社区  · 14 年前

    是否有任何方法可以将C对象的整个类定义保存到文件/数据存储区?

    我用 [可序列化] 标签和 可分割的 接口已经这样做了,但这两者都依赖于运行时程序集中的对象定义。

    我要寻找的是以下场景的解决方案:

    1)用户创建对象 类名 在我的软件中保存

    就本例而言, 类名 是不依赖系统中任何其他类的独立对象:

    也就是说,这可能是整个定义:

    public class MyClass
    {
        public int MyProperty { get; set; }
        public void DoSomething() { /* do something, like Console.Write(""); */ }
    }
    

    2)我们释放一个补丁,移除 类名 从系统

    3)用户加载保存的 类名 从步骤1和调用 剂量学() 在它上面-并且函数的工作方式与补丁从系统中移除类之前完全相同


    在没有反射/发射诡计的情况下,是否有任何方法可以做到这一点?

    3 回复  |  直到 14 年前
        1
  •  3
  •   Philip Rieck    14 年前

    不,如果不发出类型定义,这将无法工作。您要做的是实际保存代码(否则,如何 DoSomething 工作?)-这就是编译器为您所做的。在这里,简单的序列化永远不会对您起作用。

    因此,如果需要保存行为和状态,则需要保留历史代码,使用某种类型的反射发出技巧将类型定义持久化为可加载程序集,或者使用将数据视为可执行代码的动态编程技巧。

    当我以前做过版本化序列化时,我通常在对象上有自定义的序列化逻辑和一个“version”属性-使用这个,我可以创建一个我已经移动并重命名的类型-比如 SomeClass Archive.SomeClassV3 . 你可以使用 Version Tolerant Serialization 但我更喜欢执行 ISerializable 如果需要,请使用序列化代理。(事实上,我更愿意完全避免这个问题!)

        2
  •  0
  •   Pandincus    14 年前

    好吧,您可以将所有这些可序列化类保存在它们自己的DLL中,用应用程序打包这些DLL,并在运行时加载这些DLL。这样,即使从应用程序的最新版本中移除类,加载的DLL仍然可以工作。

    这似乎是一个可怕的方法,尽管…现在,您的客户机正在运行源代码管理存储库中甚至不再有的古老代码。你应该如何调试它?

        3
  •  0
  •   Genius    14 年前

    您所说的不是类属性序列化,而是进程序列化(或方法-不重要)。但与属性序列化不同,它应该包含在需要时运行的MSIL代码。因此,您必须以某种方式将其转换为bin代码,然后由assembly.load运行。我想这不是一个简单的方法。因此,如果可能的话-将MyClass的实现存储到一个单独的dll中,或者作为一个字符串(使用C语言),以便通过反射进一步编译和执行。