奇异模板加编译时自省加静态构造是成功,以自动序化,解序为例

原文地址
作者:h.s.teoh

最近,我需要扩展简单序化系统,来处理多态对象.
昨天,我发现个优秀解决方案:用crtp(奇异递归模板),来注入方法至继承类.

class Saveable(Derived, Base) : Base {
    static if (is(Base == Object)) {//基类
        // 顶级虚函数
        void save() { ... }
    } else {
        //继承类,盖
        override void save() { ... }
    }
}

class Base : Saveable!(Base, Object) { ...  }
class Derived1 : Saveable!(Derived1, Base) { ... }
class Derived2 : Saveable!(Derived1, Base) { ... }

奇异声明在类的第1行,很难丢失.可保存参数,使我们容易注入盖方法至类层次,并区别基类/继承类.
可保存保存方法,用模板参数来自省继承类并生成序化字段代码.在序化输出中它包含生成标识类型的标签的代码.从而完成了一半序化.
为了解序,可以用对象.工厂.但接口太旧,且从正确类型中读回字段有断开,因而可以用静态构造器来修复.

alias Loader = Object function(InputFile);
Loader[string] classLoaders;

class Saveable(Derived, Base) : Base {
    static if (is(Base == Object)) {//基类
        // 顶级虚函数
        void save() { ... }
    } else {
        //继承类,盖
        override void save() { ... }
    }
    static this()//静态构造器.
    {
        classLoaders[Derived.stringof] = (InputFile f) {
            auto result = new Derived;
            ... //用自省来读回继承的字段
            return result;
        };
    }
}

这儿神奇的地方是,每个可保存的实例生成一个静 本()块,有继承类的全部编译时信息.所以函数字面可用编译时自省来生成可序化代码.然后通过以类名作为来注册函数字面全局加载表.(为了简单,这里我用.的串,对大规模项目,你可用.的混杂).
因为,静 本块在启动程序,加载动态库时运行.确保启动程序类加载器有程序要用的所有信息.所以解序代码可简单在类加载器中查找保存的类型签.并调用函数指针重构对象.结果是,为可序化任何类,你只需要用:

class MyClass : Saveable!(MyClass, MyBase) { ... }

替换:

class MyClass : MyBase { ... }

其他所有全部自动搞好.不需要插件,重复序化类,运行时类型信息,甚至还支持动态库加载的类定义.只要你用Runtime.loadLibrary来确保运行静态构造器.因为静态构造器注入任何新类加载器至类加载器.并自动教会解序代码如何解序.
奇异模板+编译时自省+静态构造==成功!

posted @   zjh6  阅读(8)  评论(0编辑  收藏  举报  
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示