четверг, 24 января 2008 г.

CLR memory managment

C# использует среду выполнения CLR. В этой среде предусмотрен механизм автоматического управления памятью, что полностью позволяет забыть об удалении объектов, освобождении памяти, закрытии соединении к базам данных и открытых дескрипторов файлов. После чего можно откинуться на спинку стула и во всю наслаждаться этим процессом со связанными руками.

Конечно, у любого объекта возможно принудительно вызвать метод Close() и таким образом добиться освобождения ресурса, однако любое возникшее исключение ставит под сомнение эффективность данного механизма. В свою очередь разработчики предлагают бороться со случайными ошибками используя конструкцию обработки исключений. Следовательно если раньше за освобождение ресурса отвечала часть кода описанная в деструкторе, то теперь этот необходимо размножать по всему проекту:

MyClass myClass = GetMyClass();
try
{
 myClass.DoSomething();
}
finally
{
 IDisposable disposable = myClass as IDisposable;
 if (disposable != null) disposable.Dispose();
} 
 
Эта конструкция немного сокращается и заменяться на аналогичную, меньшую по размерам:

using (MyClass myClass = GetMyClass())
{
 myClass.DoSomething();
}

Что само по себе не несет принципиальных отличий.

Со своей стороны я хотел бы задать вопрос разработчикам почему необходимо было портить устоявшийся синтаксис и вводить дополнительные ухищрения, когда можно было использовать специальный атрибут в определении класса, который уходит от оптимального распределения памяти к менее эффективному, но более предсказуемому с подсчетом ссылок или уж в крайнем случае автоматическому генерации данной конструкции из ходя из зоны видимости переменной.

[Disposable]
class MyClass
{
 ~MyClass()
 {
    CloseDatabase();
 }
} 

Links:

1 коммент.:

  1. не, аналог using'а - это прямой каст, который еще во время компиляции проверяется

    MyClass myClass;
    try
    {
    myClass = GetMyClass();
    myClass.DoSomething();
    }
    finally
    {
    var disposable = ( IDisposable ) myClass;
    if( disposable != null ) disposable.Dispose();
    }

    + еще инициализатор в самом try

    ОтветитьУдалить