Если структуры могут реализовывать IDisposable, почему у них не может быть деструкторов? - PullRequest
0 голосов
/ 02 мая 2018

Я прочитал принятый ответ на аналогичный вопрос , часть ответа:

когда структуры передаются как параметры, они передаются по значению: они копируются. Теперь у вас есть две структуры с одинаковыми внутренними полями, и они оба попытаются очистить один и тот же объект. Один будет происходить первым, и поэтому код, который использует другой потом начнёт таинственно проваливаться ... а потом его собственная очистка не удастся

Разве эта проблема не относится к Dispose()? Если структуры могут реализовывать IDisposable, какова причина, по которой они не позволяют иметь финализаторы?

Если весь смысл финализатора в том, чтобы вызывать Dispose(false), если программист забыл вызвать Dispose(), а структуры могут иметь IDisposable.Dispose(), то зачем запрещать финализаторы для структур, но разрешать их для ссылочных типов?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Не относится ли эта же проблема к Dispose()?

Вроде, но не полностью. В частности, «тогда его собственная очистка не удастся» возможна, но маловероятна, поскольку Dispose() должен быть безопасным для вызова несколько раз для одного и того же объекта, и, как правило, не будет проблемой вызывать его несколько раз для разных копий тот же объект.

Если структуры не могут иметь финализаторы, почему им разрешено реализовывать IDisposable?

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


Йероен Мостерт добавляет, что для структур может иметь смысл даже реализовать IDisposable:

IDisposable может быть реализован просто потому, что это требование какого-то другого кода, даже если реализация Dispose() для этого конкретного типа абсолютно ничего не сделает. В этом случае нет риска случайно вызвать его в другой копии. Примером этого является случай, когда структура реализует IEnumerator<T>, где IEnumerator<T> в свою очередь реализует IDisposable.

0 голосов
/ 02 мая 2018

Потому что IDisposable это просто интерфейс. Там нет особой обработки к этому. Структуры могут реализовывать интерфейсы, поэтому они могут реализовывать IDisposable.

Однако это не значит, что в этом нет никакого смысла. Цель IDisposable - освободить неуправляемые ресурсы. Структура может иметь ссылку на неуправляемый ресурс, и это выиграет от Dispose (само собой разумеется, что сама ссылка должна реализовывать IDisposable и иметь финализатор).

В качестве бонуса Dispose часто используется как часть шаблона using. Вы создаете экземпляр только для блока using, сохраняете ссылку до Dispose, никаких странностей не возникает. На самом деле нет никаких оснований запрещать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...