Re[12]: using Statement и отложенная инициализация
От: amx3000 Россия  
Дата: 29.12.08 08:22
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Если вызывать явно, то нужно самому оборачивать в try\finally, чего не хочется.


Я не про хочется/не хочется, я про прозрачность (=сопровождаемость) кода говорю. Понятное дело, только про мое личное понимание прозрачности кода.

_FR>Это подходит только для локальных переменных (и то не всех), но не подходит для полей класса или параметров методов.


Есть мнение, что нужно проектировать классы и методы таким образом, чтобы не было необходимости использовать using с полями класса или параметрами методов.
Само собой, речь я веду об идеальной ситуации, к которой следует стремиться. А не про реальный мир, в котором обычно все уже спроектировано кем-то, причем далеко не идеально. Увы.

_FR>В качестве примера такой задачи предлагаю написать функцию, которой передаётся путь к файлу, а вернуть она должна стрим к этому файлу (не закрытый, естественно), но только если первые байты в файле 0x11111111. Если файла нет, или прервые байты в нём не такие, то вернуть следует Stream.Null.


Предложение понятно и ответ очевиден — если условия задачи настолько жесткие, то следует делать по-Вашему, либо не использовать using, а использовать try/finally и Dispose вручную.

Но при решении аналогичной задачи я бы все же проектировал классы/методы по-другому, чтобы в подобной функции не возникало необходимости.
То есть вместо
{
    // ...

    стрим = GetПравильныйСтримИлиStreamNull(fileName);
    ДелатьЧтотоСоСтримомКоторыйВполнеМожетБытьStreamNullАМожетИНеБыть(стрим);

    // ...
}

Stream GetПравильныйСтримИлиStreamNull(string fileName)
{
    // тут творим нечто странное и на мой взгляд плохочитаемое c using'ом 
    // и возвращаем то ли FileStream, то ли Stream.Null
}

делал бы что-то вроде
{
    // ...

    if (File.Exists(fileName))
    {
        using (Stream стрим = new FileStream(fileName, FileMode.Open))
        {
            bool isStreamValid = ПроверитьНа0х11111111вНачалеСтрима(стрим);
            if (isStreamValid)
            {
                ДелатьЧтотоСЗаведомоПравильнымСтримом(стрим);
            }
            else
            {
                ДелатьЧтотоСоStreamNullЧтоСамоПоСебеВыглядитНесколькоСтранно(Stream.Null);
            }
        }
    }
    else
    {
        ДелатьЧтотоСоStreamNullЧтоСамоПоСебеВыглядитНесколькоСтранно(Stream.Null);
    }

   // ...
}

Правда, должен признаться, мне этот код тоже не очень нравится (два одинаковых блока else). Навскидку, скорее всего после using следует делать return, блоки else убрать, а их содержимое вынести после блока if. Возможно, посидев, подумав, придумал бы что-то более симпатичное, сейчас времени нет, извините.

Кстати, не подскажете практический пример, для чего нужна была бы работа со Stream.Null? Кроме тестовых целей, как-то ничего в голову не приходит.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.