简体   繁体   中英

Inheritance with async/await initialization methods

My class has properties that need to be initialized. As I don't want to pass through a partially constructed object, and constructors can't/shouldn't be made async, I have been using the Factory Pattern described here , so my class looks like this:

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

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

So far that pattern has served me well, but now I need to implement other classes that will extend BaseClass and will have other async properties that need to be initialized before their objects can be used.

My initial plan was to simply override the CreateObject() method, but static methods can't be made virtual/override. I have then decided to hide the CreateObject() method in the base class and have a new CreateObject() method in the derived class that looks like this:

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;
    }
}

Needless to say that for every derived class I need to rewrite the initialization of the inherited properties. That alone goes against the whole inheritance concept, but the worst part is that some of these new async properties in the derived classes depend on the old async properties in the base class, but I can't simply call on them inside the CreateObject() method because they are not static properties.

Is there any way I can improve on what I have at the moment, work around this Catch22 issue, and achieve what was described above?

[EDIT]

Just to give a bit of context, the reason why I don't want to depend on initialization methods called outside my classes is that I may not have control over the code creating objects and calling such initialization methods. That is why I would rather return a "ready to use" object back to the caller.

I think you should read Stephen Cleary's very next post stating that it's an oxymoron to have your asynchronously initialized object have an API that exposes a public non-asychronous property ( AsyncProp1 ). This amounts to wanting an async property.

You could redesign the interface to this object so that any of its methods are also async and just let those methods internally ensure that it is initialized (awaiting InitAsync if necessary). ...if preventing misuse is your primary goal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM