d的反射示例

反射示例

import std.stdio;
import std.conv;
import std.traits;

class MyClass {
  void myMethod() {}
  int anotherMethod(int a) { return a; }

  // 运行时桥函数,技巧是编译时反射生成`开关`
  string call(string methodName, string[] args) {
    // 普通的开关
    method_switch: switch(methodName) {
      // 静每一迭代__traits(allMembers)
      static foreach(inspecting; __traits(allMembers, typeof(this))) {
        case inspecting: { 
// 创建开关,这里只用可调用方法,如果可调用
          static if(isCallable!(__traits(getMember, this, inspecting))) {
            auto callable = &__traits(getMember, this, inspecting);
            // 构建参数列表
            Parameters!callable arguments;
            foreach(i, ref arg; arguments) { // 设置成员,因而用引用
              // 当作串,并转为实际方法参数
              //__traits(compiles)判断是否可编译
              // 用static if转换编译时错误为运行时异常
              static if(__traits(compiles, to!(typeof(arg))(args[i])))
                arg = to!(typeof(arg))(args[i]);
              else
                // 可能抛异常
                throw new Exception("method " ~ methodName ~ "不匹配");
            }

            static if(is(ReturnType!callable == void)) {
              // 处理返回
              callable(arguments);
              return null;
            } else {
              return to!string(callable(arguments));
            }
          }
        } break method_switch;
      }
      default:
        throw new Exception("无此方法" ~ methodName);
    }

    assert(0); // 不可达
  }
}

void main() {
  auto obj = new MyClass();
  writeln(obj.call("myMethod", []));
  writeln(obj.call("anotherMethod", ["5"]));
}

还可把call作为接口.

class MyNewClass : Reflectable {
    mixin CallImplementation;
}

破解,核心运行时库,甚至可自动反射.
使用接口,还可给类加静态构造器,并注册到运行时关联数组开关类名到工厂函数,并从创建它们.

posted @   zjh6  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示