C# 使用异步/等待初始化方法继承

C# 使用异步/等待初始化方法继承,c#,inheritance,constructor,async-await,static-methods,C#,Inheritance,Constructor,Async Await,Static Methods,我的类具有需要初始化的属性。由于我不想通过一个部分构造的对象,并且构造函数不能/不应该是异步的,所以我一直在使用所描述的工厂模式,所以我的类如下所示: public class BaseClass { public PropType AsyncProp1 { get; set; } public static async Task<BaseClass> CreateObject() { var baseClass = new BaseClas

我的类具有需要初始化的属性。由于我不想通过一个部分构造的对象,并且构造函数不能/不应该是异步的,所以我一直在使用所描述的工厂模式,所以我的类如下所示:

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

    public static async Task<BaseClass> CreateObject()
    {
        var baseClass = new BaseClass()
        {
            AsyncProp1 = await GetProp1Async()
        };
        return baseClass;
    }
}
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;
    }
}
公共类基类
{
公共PropType AsyncProp1{get;set;}
公共静态异步任务CreateObject()
{
var baseClass=新的基类()
{
AsyncProp1=等待GetProp1Async()
};
返回基类;
}
}
到目前为止,该模式对我很有用,但现在我需要实现其他类,这些类将扩展基类,并具有其他异步属性,这些属性需要在使用它们的对象之前进行初始化

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

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

    public static async Task<BaseClass> CreateObject()
    {
        var baseClass = new BaseClass()
        {
            AsyncProp1 = await GetProp1Async()
        };
        return baseClass;
    }
}
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;
    }
}
公共类派生类:基类
{
公共PropType AsyncProp2{get;set;}
公共静态新异步任务CreateObject()
{
var derivedClass=新的derivedClass()
{
AsyncProp1=等待GetProp1Async(),
AsyncProp2=await GetProp2Async(AsyncProp1)//不能这样做-AsyncProp1不是静态的
};
返回派生类;
}
}
不用说,对于每个派生类,我都需要重写继承属性的初始化。这本身就违背了整个继承概念,但最糟糕的是,派生类中的一些新异步属性依赖于基类中的旧异步属性,但我不能在CreateObject()方法中简单地调用它们,因为它们不是静态属性

有什么办法可以改进我目前的情况,解决这个问题,实现上面所描述的吗

[编辑]


我不想依赖于类外调用的初始化方法的原因是,我可能无法控制创建对象和调用此类初始化方法的代码。这就是为什么我宁愿将一个“随时可用”的对象返回给调用者。

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


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

创建对象后调用单个虚拟异步初始化函数如何?(即,不使用createobject函数,只需要调用方调用async Init即可)@Wyck我相信您的建议在某种程度上就是所描述的“异步初始化模式”。即使没有任务,只要使用var newObject=new BaseClass(),我也可以做到这一点;后跟wait newObject.InitAsync();在我的电话里。但正如我之前解释的那样,我宁愿避免这种情况。我认为您应该阅读Stephen Cleary的文章,其中指出,让异步初始化的对象具有公开公共非异步属性(
AsyncProp1
)的api是一种矛盾的说法。这相当于需要一个异步属性。您可以重新设计此对象的接口,使其任何方法都是异步的,只需让这些方法在内部确保其已初始化(如有必要,等待InitAsync)。。。如果防止误用是您的主要目标,请注意:我倾向于选择单独的工厂类型(与静态
CreateAsync
)相反。但每种情况都不同;有时,
AsyncLazy
正是您想要的(缺点是每个读取的属性都需要一个
wait
)。当我写这些博客文章时,我希望DI容器能够采用某种异步创建模式。然而,这似乎永远不会发生。@StephenCleary首先,谢谢你的文章。我是异步编程新手,他们帮了我很多。读了你的评论后,我又回去查看了一下,才意识到是你在8年前写的!令人印象深刻的是,在经历了这么长时间之后,他们仍然很有帮助,而且是最新的,特别是在像我们这样的领域。再次感谢!