Я полагаю, что другой альтернативой, которую вы могли бы использовать, является обертывание ваших экземпляров одноразовым типом, чтобы он мог автоматически обрабатывать удаление типа независимо от того, является ли тип фактически одноразовым.Например, я мог бы определить что-то вроде:
public class DisposableWrapper<T> : IDisposable
{
private readonly T _instance;
private readonly IDisposable _disposable;
public DisposableWrapper(T instance)
{
_instance = instance;
_disposable = instance as IDisposable;
}
public void Dispose()
{
if (_disposable != null)
_disposable.Dispose();
}
public static implicit operator T(DisposableWrapper<T> disposableWrapper)
{
return disposableWrapper._instance;
}
}
(Надеюсь, с немного большей обработкой ошибок!)
Учитывая, что я знаю в точке утилизации, является ли тип одноразовым, я могуназовите это соответственно.Я также могу предоставить неявный оператор для приведения к нему внутреннего типа.С учетом вышеизложенного и изящного метода расширения:
public static class DisposableExtensions
{
public static DisposableWrapper<T> Wrap<T>(this T instance)
{
return new DisposableWrapper<T>(instance);
}
}
Давайте представим, что у меня есть служба, которую я внедряю в тип, это может быть:
public interface IUserService
{
IUser GetUser();
}
Я мог бы потенциально сделатьчто-то вроде:
public HomeController(IUserService service)
{
using (var disposable = service.Wrap())
{
var user = service.GetUser();
// I can even grab it again, implicitly.
IUserService service2 = disposable;
}
}
Теперь, независимо от того, является ли эта конкретная реализация IUserService
одноразовой или нет, я все еще могу спокойно работать, предполагая, что это не имеет значения.
Другойпример быстрой консоли:
class Program
{
static void Main(string[] args)
{
using (var instance = new ClassA().Wrap())
{
ClassA instanceA = instance;
}
using (var instance = new ClassB().Wrap())
{
ClassB instanceB = instance;
}
Console.ReadKey();
}
}
public class ClassA
{
}
public class ClassB : IDisposable
{
public void Dispose()
{
Console.Write("Disposed");
}
}