Могу ли я запретить C ++ / CLI добавлять IDisposable в мой класс ref?
-
21-08-2019 - |
Вопрос
C ++ / CLI услужливо генерирует IDisposable
строительные леса для вас, когда вы реализуете деструктор в классе ref.Кроме того, если вы не реализуете деструктор, но в вашем классе есть переменная-член, которая реализует IDisposable
, тогда IDisposable
снова автоматически реализуется в вашем классе.Это довольно полезно и намного лучше, чем то, как IDisposable
обрабатывается на C #.
Я столкнулся с таким поведением при реализации класса ref, который содержит msclr::com::ptr
(интеллектуальный указатель, содержащий RCW).
ref class Test /* : IDisposable added by the compiler */
{
msclr::com::ptr<IWhatever> _aComObject;
}
В мой конкретный случай, COM-объект, на который ссылается мой класс, не "блокирует" какой-то неуправляемый ресурс, он фактически просто использует немного неуправляемой памяти, которую среда CLR не может видеть.Поэтому я хотел бы избежать путаницы с пользователями моего класса ref, не реализуя IDisposable
класс.Вместо этого я хочу, чтобы среда CLR знала о существовании COM-объекта, используя GC API для добавления соответствующего объема памяти.
Итак, вопрос в том,:есть ли способ подавить реализацию IDisposable
в классе ref, который не реализует деструктор, но содержит IDisposable
переменная-член?
Примечание: часто это было бы неправильным поступком, поскольку это помешало бы пользователям класса детерминированно распоряжаться базовым COM-объектом, но, учитывая конкретные обстоятельства, предоставление IDisposable
потенциально может сбить с толку пользователей моего класса ref, поскольку на самом деле нет необходимости удалять класс ref, о котором идет речь.
Я полагаю, одним из вариантов было бы реализовать вариант msclr:: com:: ptr без деструктора.
Мы были бы признательны за любой другой метод подавления автоматического добавления IDisposable .Спасибо.
Ответ
Объявлять _aComObject
в качестве дескриптора msclr::com::ptr (msclr::com::ptr<IWhatever>^
).Тогда компилятор не учитывает Test
как являющийся "владельцем" объекта com ptr, и не распоряжается им при удалении Test.
Решение
Я думаю, что ответ заключается в том, чтобы провести ручка к msclr:: com:: ptr вместо того, чтобы хранить его "по значению" (которое все еще хранит его как дескриптор "за кулисами", за исключением того, что компилятор C ++ CLI обрабатывает его как значение - "удаляя" его (вызывая Dispose), когда объект owner удаляется (утилизируется)).
Другие советы
Я не уверен, что согласен с ratioanle для избежания реализации IDispose - но почему бы просто не сохранить IWhatever * в вашем классе.В этом случае компилятор не должен генерировать IDisposable реализацию.
Если вам не нужно поведение деструктора, то какую выгоду вам дает оболочка com:: ptr, которую вы покупаете?Вы всегда можете объявить com::ptr в стеке и присвоить ему свой указатель на член в любом заданном методе, если вам это действительно нужно.