方法只能在对象初始化后调用——如何进行?

A method can only be called after the object is initialized - how to proceed?

我在日常编码中发现了一个反复出现的模式,如下所示:

var foo = new Foo();
foo.Initialize(params);
foo.DoSomething();

在这些情况下,foo.Initialize 是绝对需要的,这样它才能真正 DoSomething,否则某些 foo 属性仍将 null/未初始化。

有规律吗?如何安全地确定 DoSomething 将 only/always 在 Initialize 之后被调用 ?如果没有,如何继续:我应该提出异常,静默忽略它,检查一些标志...?

本质上你是在说 Initialize 是一个 构造函数 。所以该代码确实应该是构造函数的一部分:

var foo = new Foo(params);
foo.DoSomething();

这正是构造函数的用途:它是保证在任何对象方法 运行 之前 运行 的代码,它的工作是检查 pre-conditions 并提供运行.

的其他对象方法的健全环境

如果在初始化过程中确实有 大量 的工作,那么我当然可以看到它是 "too much to put in a constructor" 的说法。 (我敢肯定,对幕后语言机制有更深入了解的人可以就此事提供一些令人信服的解释,但我不是那个人。)

在我看来,工厂在这里很有用。像这样:

public class Foo
{
    private Foo()
    {
        // trivial initialization operations
    }

    private void Initialize(SomeType params)
    {
        // non-trivial initialization operations
    }

    public static Foo CreateNew(SomeType params)
    {
        var result = new Foo();
        result.Initialize(params);
        return result;
    }
}

消费代码变为:

var foo = Foo.CreateNew(params);
foo.DoSomething();

所有方式的附加逻辑都可以放入该工厂,包括 params 的各种健全性检查或验证繁重的初始化操作是否成功完成(例如它们是否依赖外部资源)。这也是注入依赖项的好地方。

这基本上归结为完全分离关注点的问题。构造函数的工作是创建对象的实例,初始化程序的工作是让复杂对象准备好用于预期用途,工厂的工作是协调这些工作,只有 return ready-for-use 个对象(处理相应的任何错误)。