在不调用构造函数的情况下创建实例

时间:2014-02-01 16:30:10

标签: dependency-injection d

我想创建一个实例,注入几个字段,然后再调用该实例上的构造函数。

示例:

class Foo {
    int a = 50;
    int b;

    this() {
        assert(a == 50 && b == 10);
    }
}

...

Foo bar = ???;
bar.b = 10;
bar.this();

通常,Foo可能有多个重载的构造函数。 在不干扰垃圾收集器和其他语言机制的情况下,最好的方法是什么?


编辑:到目前为止我收到的大多数回答都是“为什么你想要那样做?”

我目前正在使用这样的@ Annotation驱动系统来实现两件事:自动配置加载和自动依赖注入。到目前为止,两者都显示出对我来说生产率大幅增加,并且它们也为责任脱钩创造了奇迹。 (另见:Single responsibility principle

虽然在D中可能并不常见,但类似的方法在Java等其他语言中被广泛使用。

1 个答案:

答案 0 :(得分:4)

我会说你应该改变你的构造函数来接受这些论点。

但如果你真的想,你可以分手“bar = new Foo();”分三步:

  • 使用适当的大小(__traits(classInstanceSize
  • 分配内存
  • 使用适当的内容初始化内存(typeid().init - 这样可以保存像a = 50,指向虚拟表的指针等的值。)
  • 调用构造函数

当然,返回新的参考资料。

import core.memory; // for GC.malloc
enum size = __traits(classInstanceSize, Foo); // get the size
auto memory = GC.malloc(size)[0 .. size]; // alloc mem and slice it for bounds checking
memory[] = typeid(Foo).init[]; // initialize the memory

Foo foo = cast(Foo) memory.ptr; // we can now cast it to the reference

foo.b = 10; // here's your special line

foo.__ctor(); // and now call the constructor. Can pass any arguments here, D will handle the overloads normally

assert(foo.a == 50); // ensure everything worked
assert(foo.b == 10);
assert(typeid(foo) == typeid(Foo));

// BTW don't use the variable memory anymore - only use the typed Foo instance

如果需要,分解这样的步骤还可以替换分配方法。 Phobos'std.conv.emplace函数在单个函数中执行第2步和第3步,以便通过自定义分配使其更容易。

但是既然你想在第2步和第3步之间插入代码,你必须自己动手。