首页 > 解决方案 > 使用 async/await 初始化方法继承

问题描述

我的类有需要初始化的属性。由于我不想通过部分构造的对象,并且构造函数不能/不应该异步,我一直在使用这里描述的工厂模式,所以我的类看起来像这样:

public class BaseClass
{
    public PropType AsyncProp1 { get; set; }

    public static async Task<BaseClass> CreateObject()
    {
        var baseClass = new BaseClass()
        {
            AsyncProp1 = await GetProp1Async()
        };
        return baseClass;
    }
}

到目前为止,该模式对我很有帮助,但现在我需要实现其他类,这些类将扩展 BaseClass 并具有其他需要在使用它们的对象之前初始化的异步属性。

我最初的计划是简单地覆盖 CreateObject() 方法,但不能将静态方法设为虚拟/覆盖。然后我决定在基类中隐藏 CreateObject() 方法,并在派生类中添加一个新的 CreateObject() 方法,如下所示:

public class DerivedClass : BaseClass
{
    public PropType AsyncProp2 { get; set; }

    public static new async Task<DerivedClass> CreateObject()
    {
        var derivedClass = new DerivedClass()
        {
            AsyncProp1 = await GetProp1Async(),
            AsyncProp2 = await GetProp2Async(AsyncProp1) // can't do that - AsyncProp1 is not static
        };
        return derivedClass;
    }
}

不用说,对于每个派生类,我都需要重写继承属性的初始化。仅此一项就违背了整个继承概念,但最糟糕的是派生类中的一些新异步属性依赖于基类中的旧异步属性,但我不能简单地在 CreateObject() 中调用它们方法,因为它们不是静态属性。

有什么办法可以改进我目前所拥有的,解决这个 Catch22 问题,并实现上述目标?

[编辑]

只是为了提供一些上下文,我不想依赖在我的类之外调用的初始化方法的原因是我可能无法控制创建对象和调用此类初始化方法的代码。这就是为什么我宁愿将“准备使用”对象返回给调用者。

标签: c#inheritanceconstructorasync-awaitstatic-methods

解决方案


我认为你应该阅读 Stephen Cleary 的下一篇文章,他说让你的异步初始化对象有一个公开公共非异步属性 ( AsyncProp1) 的 API 是矛盾的。这相当于想要一个异步属性。

您可以重新设计此对象的接口,使其任何方法也是异步的,并让这些方法在内部确保它已初始化(InitAsync如有必要等待)。...如果防止滥用是您的主要目标。


推荐阅读