Ваша проблема сопоставима с созданием файлового объекта и открытием файла.На самом деле существует множество классов, в которых вам нужно выполнить два шага, прежде чем вы сможете использовать объект: create + Initialize (часто называемый чем-то похожим на Open).
Преимущество этого состоит в том, что конструктор можетбыть легкимПри желании вы можете изменить некоторые свойства перед фактической инициализацией объекта.Когда все свойства установлены, вызывается функция Initialize
/ Open
для подготовки объекта к использованию.Эта Initialize
функция может быть асинхронной.
Недостатком является то, что вы должны доверять пользователю вашего класса, который он вызовет Initialize()
, прежде чем он использует любую другую функцию вашего класса.На самом деле, если вы хотите сделать ваш класс полным доказательством (дурака?), Вы должны проверять каждую функцию, что был вызван Initialize()
.
Шаблон, облегчающий эту задачу, заключается в объявлении конструктора частными создайте общедоступную статическую функцию, которая будет создавать объект и вызывать Initialize()
перед возвратом созданного объекта.Таким образом, вы будете знать, что каждый, кто имеет доступ к объекту, использовал функцию * 1013. *
В этом примере показан класс, имитирующий требуемый асинхронный конструктор
public MyClass
{
public static async Task<MyClass> CreateAsync(...)
{
MyClass x = new MyClass();
await x.InitializeAsync(...)
return x;
}
// make sure no one but the Create function can call the constructor:
private MyClass(){}
private async Task InitializeAsync(...)
{
// do the async things you wanted to do in your async constructor
}
public async Task<int> OtherFunctionAsync(int a, int b)
{
return await OtherFunctionAsync(a, b);
}
Использование будетбыть следующим:
public async Task<int> SomethingAsync()
{
// Create and initialize a MyClass object
MyClass myObject = await MyClass.CreateAsync(...);
// use the created object:
return await myObject.OtherFunctionAsync(4, 7);
}