Они работают таким образом, что при желании вы можете определить один из них для класса, понимая при этом, что клиентский код обязан явно вызывать этот метод для освобождения ресурсов. Ресурсы освобождаются сразу после того, как отпадает надобность в них. Недостаток: вы полагаетесь на то, что клиентский код будет вести себя корректно и вызовет этот метод (однако это может и не произойти).
Типичное решение – использование Dispose() и Close() совместно с Finalize():
public class myClass : MasterClass
{
private int x;
public void Dispose()
{
// освобождаем ресурсы
//...
GC.SuppressFinalize(this);
// для объекта (this) не
// нужно больше вызивать Finalize
}
protected override void Finalize()
{
// освобождаем ресурсы
base.Finalize();
}
}
В приведенном примере: Если клиентский код не забудет вызвать Dispose(), ресурсы будут освобождены вовремя. Если же забудет, то Finalize() будет вызван при сборке мусора. Метод GC.SuppressFinalize() информирует среду исполнения о том, что для объекта переданного в качестве параметра не нужно больше вызывать Finalize().
Разница между Close() и Dispose() состоит главным образом в соглашении о их применению. Close() предполагает, что ресурс может быть позже открыт, в то время как вызов Dispose() означает, что клиент закончил работу с этим ресурсом навсегда. Можно реализовать оба метода.
C# предлагает синтаксис, который можно использовать для гарантии того, что Dispose (но не Close() (!) будет вызван для объекта автоматически, и его не нужно вызывать вручную, когда ссылка на него выйдет из области видимости (using):
Выражение using, за которым в скобках следует определение переменной по ссылке, поместит эту переменную в область видимости, задаваемую фигурными скобками. Когда переменная выйдет из этой области видимости, будет автоматически вызван ее метод Dispose().
Лучшая альтернатива определить класс унаследованным от интерфейса IDisposable:
public class RessourceG : IDisposable
{
public void Dispose()
{
Console.WriteLine("Resource Dispose!");
}
}
Наследование от IDisposable вынуждает производный класс реализовать метод Dispose(), если этого не будет сделано, возникает ошибка при компиляции. Выигрыш – компилятор может убедиться, что объект определенный в выражении using имеет метод Dispose(), который он может вызвать автоматически.
Do'stlaringiz bilan baham: |