Ваше второе предложение будет работать, только если IEngine
реализует IDisposable
или если к параметру типа на EngineDriver
добавлено дополнительное ограничение (для IDisposable
). Исходный код достаточно гибок, чтобы дополнительно обрабатывать IEngine
реализаций, которые также реализуют IDisposable
.
Если вы действительно беспокоитесь об использовании объекта после его удаления, вы можете создать еще одну область видимости для переменной:
public class EngineDriver<T> where T : IEngine, new() {
public void GetThingsDone() {
{
T driver = new T();
using (driver as IDisposable) {
driver.DoWork();
}
}
}
}
Но для этого примера это перебор; сфера применения метода достаточна. Это имело бы смысл только в том случае, если ваш метод был бы больше, например:
public class EngineDriver<T> where T : IEngine, new() {
public void GetThingsDone() {
{
T driver = new T();
using (driver as IDisposable) {
driver.DoWork();
}
}
// do more stuff, can't access driver here ....
}
}
Но опять же, я просто показываю, что здесь возможно, я бы предпочел реорганизовать его так, чтобы этот блок был изолирован от другого кода.
У вас также может быть еще один обзорный класс:
public class DisposableWrapper<T> : IDisposable {
public T Item { get; private set; }
public DisposableWrapper(T item) { Item = item; }
public void Dispose() {
using (Item as IDisposable) { }
Item = default(T);
}
}
public static class DisposableWrapperExtensions {
public static DisposableWrapper<T> AsDisposable<T>(this T item) {
return new DisposableWrapper<T>(item);
}
}
public class EngineDriver<T> where T : IEngine, new() {
public void GetThingsDone() {
using (var driver = new T().AsDisposable()) {
driver.Item.DoWork();
}
}
}
Это может иметь смысл, если вы используете много ссылок на интерфейсы, которые может реализовать IDisposable
.