Предполагая, что у вас есть какой-то созданный фабрикой ресурс, который все еще будет принадлежать фабрике после строительства, как это:
public class Resource : IDisposable {
public void Dispose() { /* ... */ }
}
public class ResourceManager : IDisposable {
public Resource Load() { /* create resource and add to list */ }
public void Dispose() { /* dispose all loaded resources in list */ }
}
Теперь у вас есть базовый класс, для инициализации которого требуется экземпляр Resource
в конструкторе:
public class Fooificator {
public Fooificator(Resource resource) {
this.resource = resource;
}
private Resource resource;
}
Как класс, производный от такого базового класса, может создать Resource
без потери ссылки на фабрику?
Наивный подход, использующий статический метод, не позволяет запоминать фабрику (кроме уродливых хаков, таких как хранение ее в статическом поле, которое конструктор может выбрать после завершения построения базового класса, или использования двухэтапной инициализации где Resource
предоставляется базовому классу через конструктор, называемый методом Initialize()
)
public class DefaultFooificator : Fooificator {
public DefaultFooificator() : base(loadDefaultResource()) {}
private static Resource loadDefaultResource() {
ResourceManager resourceManager = new ResourceManager();
return resourceManager.Load();
// Bad: losing reference to ResourceManager here!
}
}
Одним из возможных обходных путей будет именованный конструктор:
public class DefaultFooificator : Fooificator, IDisposable {
public static DefaultFooificator Create() {
ResourceManager resourceManager = new ResourceManager();
DefaultFooificator fooificator = new DefaultFooificator(
resourceManager.Load()
);
fooificator.resourceManager = resourceManager;
return fooificator;
}
private DefaultFooificator(Resource resource) : base(resource) {}
private ResourceManager resourceManager;
}
Однако, при решении проблемы сохранения ссылки ResourceManager
, это не позволит дальнейшим классам наследовать от DefaultFooificator
.
Существуют ли какие-либо элегантные решения, которые позволили бы мне в дальнейшем извлечь из DefaultFooificator
или сохранить ссылку ResourceManager
другим способом?