3

我遇到了一个很容易解决但我年轻时还没有遇到过的设计问题。

我有一门课需要经过一些设置程序才能发生其他任何事情。

但是,在构建这个类的过程中,我在构造函数的参数中有一个可以传递的委托,以便用户可以将自己的信息添加到类中。

但是,当调用 this 时,创建类的范围仍然没有有效的实例,因此会发生空异常错误。

我该如何围绕这个设计?我应该将“this”的实例传递给该委托吗?

在这里做出什么是好的决定?我有一个“StartServices()”方法,我可以轻松地调用委托,但我觉得设计明智,它应该在构造函数中。

感谢您的建议!

4

5 回答 5

6

听起来您想传递一个Action<T>或类似的),因此无论何时该类需要委托,它都可以调用; 例如:theDelegate(this)

var instance = new SomeType(..., obj => { /* extra code invovling obj */ });

然后obj将是创建时的实例,它的优点是编译器生成的方法不需要任何状态/捕获(除非您自己需要)。

然而!我会谨慎地在构造函数中调用委托,出于同样的原因virtual应该谨慎对待 - 在深层对象模型中,整个类可能不会在您的中级构造函数(调用委托或重写)处完全创建method) 触发,提供对处于不完整状态的对象的狡猾访问。

于 2009-12-28T23:05:19.453 回答
4

考虑使用工厂方法

public class MyClass
{
    private MyClass() {}

    public static MyClass Create(delegate d ...)
    {
        var instance = new MyClass();
        d.(instance);
        return instance;
    }
}

然后像这样使用它:

var o = MyClass.Create(...);

您也可以参加工厂课程:

var o = factory.CreateMyClass(...);
于 2009-12-28T23:07:13.680 回答
3

我建议不要在构造函数中使用委托。委托可以轻松访问其他线程上的数据,从而导致一些不明显的副作用。在这种情况下,您应该拆分类创建和类初始化。

使用工厂模式将帮助您清楚地分开创建复杂对象的责任,但不需要对象初始化。我确实认为将行为注入构造函数是一种反模式。

您的问题的解决方案可以是将行为作为(对象)依赖项与定义良好的接口注入。您希望将代表传递到构造中是对我的关注点分离不佳和违反 SingelResponsibilityPrinciple 的标志。

于 2009-12-28T23:23:24.023 回答
2

基本上,听起来您想要的代码根本不应该在构造函数中。构造函数是创建对象的对象。在它退出之前,不能保证对象“正常工作”。现在,它可能会工作,是的,您可以获得this指针,但调用代码会期望它完全构造。所以从设计的角度来看,这不是一个好的做法。只需在构造函数之后调用另一个方法(如果这有助于您的多态性,则使用接口)。

于 2009-12-28T23:08:38.157 回答
0

这种方法似乎很奇怪,通过代表完成了什么样的设置工作?

也许在构造函数的末尾引发一个事件会是一个更标准的方法。

于 2009-12-28T23:12:25.283 回答