|
вопрос
|
|||
---|---|---|---|
#18+
Правильно ли сконструировали тип? Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2016, 19:56 |
|
вопрос
|
|||
---|---|---|---|
#18+
Код: c# 1.
ЕМНИП надо инициализировать, дефолтных значений C# не признает, хотя и забивает все нулями. По мне так излишество это, проще так Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2016, 20:11 |
|
вопрос
|
|||
---|---|---|---|
#18+
Dima T, да в общем то можно и добавить, класс не запечатан можно и virtual void Dispose(bool disposing) загрузить для тех кто пойдет после нас да и свойство добавить для удобства IsDisposed как у контролов, вообще уместно ли реализовывать у типа Class - IDisposable? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2016, 20:26 |
|
вопрос
|
|||
---|---|---|---|
#18+
Где-то в степиПравильно ли сконструировали тип? Не совсем, классическая реализация disposable-паттерна включает в себя два перегруженных метода Dispose - один public и без параметра, второй protected (либо private, если класс sealed) с параметром, указывающим на то, откуда происходит вызов - т.е. как-то так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
Выполнять вызов GC.SuppressFinalize при вызове Dispose из финализатора избыточно - объект уже попал в обработку из очереди на финализацию (а вот промаркировать его, как не требующего финализации, при вызове Dispose извне очень даже нужно и полезно). Плюс, если операция диспозинга сводится только к диспозингу инкапсулируемого объекта, то при вызове Dispose извне из очереди на финализацию нужно удалить и экземпляр объекта-враппера (Class). Dima TЕМНИП надо инициализировать, дефолтных значений C# не признает, хотя и забивает все нулями. Не надо: 10.4.4 Field initialization The initial value of a field, whether it be a static field or an instance field, is the default value (Section 5.2) of the field's type. Обязательны для инициализации локальные переменные, но не поля класса. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 06:36 |
|
вопрос
|
|||
---|---|---|---|
#18+
Сон Веры Павловны, то есть если класс не sealed, виртуал желателен ( писал выше) а если не sealed - то и так сойдет? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 06:42 |
|
вопрос
|
|||
---|---|---|---|
#18+
Где-то в степиСон Веры Павловны, то есть если класс не sealed, виртуал желателен ( писал выше) а если не sealed - то и так сойдет? Нет, перегрузка Dispose с параметром в общем случае нужна всегда. "И так сойдет" в том случае, если в вашем классе нужно осовбождать только managed-ресурсы, реализующие IDisposable. Если же нужно освобождать какие-то unmanaged-ресурсы (например, IntPtr на какой-нибудь буфер), то это освобождение должно выполняться всегда (см. здесь , например). И всё равно даже в таком случае рекомендуется сто раз подумать, нужен ли финализатор, т.к. сборка мусорных объектов с финализаторами намного затратнее, чем без финализаторов (у Рихтера это подробно расписано - почему и как). Рекомендуется, например, рассмотреть вариант с CriticalFinalizerObject. Резюмируя: если у вас враппится только IDisposable-объект - оставил бы, как есть, и выкинул бы финализатор. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 07:24 |
|
вопрос
|
|||
---|---|---|---|
#18+
Сон Веры Павловны, автороставил бы, как есть, и выкинул бы финализатор соглашусь,и пошел бы еще дальше - вообще бы не реализовывал диспосабле в обертке. а вот авторто это освобождение должно выполняться всегда (см. здесь, например). И всё равно даже в таком случае рекомендуется сто раз подумать, нужен ли финализатор не соглашусь, где же защита от дурака - программист проспал using? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 07:37 |
|
вопрос
|
|||
---|---|---|---|
#18+
Где-то в степи не соглашусь, где же защита от дурака - программист проспал using? Деструктор объекта вызывается сборщиком мусора, из-за этого и родились IDisposable, using и т.д. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 07:44 |
|
вопрос
|
|||
---|---|---|---|
#18+
Где-то в степине соглашусь, где же защита от дурака - программист проспал using? Выше же писал - например, CriticalFinalizerObject - это во-первых. Во-вторых - если у инкапсулируемого IDisposable есть финализатор, то у враппера он вообще не нужен. В третьих, обязательного-кровь-из-носу освобождения требуют только unmanaged-ресурсы, и то далеко не все - большинство из них автоматически освободятся при закрытии процесса (как хэндл глобального хоткея, например), так что "программист проспал using" не приведет к концу света. Dima TГде-то в степи не соглашусь, где же защита от дурака - программист проспал using? Деструктор объекта вызывается сборщиком мусора, из-за этого и родились IDisposable, using и т.д. Вовсе нет, и даже почти с точностью до наоборот - вызов Dispose вполне детерминирован и явен, в отличие от вызова финализатора. Ну, и реализация disposable-паттерна имеет усеченные варианты, в которых финализатора нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 07:59 |
|
вопрос
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныDima Tпропущено... Деструктор объекта вызывается сборщиком мусора, из-за этого и родились IDisposable, using и т.д. Вовсе нет, и даже почти с точностью до наоборот - вызов Dispose вполне детерминирован и явен, в отличие от вызова финализатора. Ну, и реализация disposable-паттерна имеет усеченные варианты, в которых финализатора нет. Нагуглил что такое финализатор ИМХУ разработчики C# накосячили в синтаксисе: ~Class() это синтаксис описания деструктора в С++, что в итоге приводит к непонимаю как работает код. Например в С++ Код: plaintext 1. 2. 3. 4.
а в C# так не произойдет. my_obj.~Class() будет вызван сборщиком мусора неизвестно когда, т.е. когда он решит сам прибраться или его об этом попросят. Поэтому в отличии от того же C++ нельзя выносить освобождение ресурсов ОС в my_obj.~Class() т.к. это не деструктор. Например прога открыла файл (закрытие файла в финализаторе), написала туда чего-нибудь и уснула в ожидании какого-нибудь события. Файл продолжает быть открытым. ИМХУ т.к. деструктора как-такого не предусмотрено, родились костыли в виде IDisposable. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 08:27 |
|
вопрос
|
|||
---|---|---|---|
#18+
Dima TИМХУ разработчики C# накосячили в синтаксисе: ~Class() это синтаксис описания деструктора в С++, что в итоге приводит к непонимаю как работает код. Рихтер, CLR via C#If you’re familiar with C++, you’ll notice that the special syntax C# requires for defining a Finalize method looks just like the syntax you’d use to define a C++ destructor. In fact, the C# Programming Language Specification calls this method a destructor. However, a Finalize method doesn’t work like an unmanaged C++ destructor at all, and this has caused a great deal of confusion for developers migrating from one language to another. The problem is that developers mistakenly believe that using the C# destructor syntax means that the type’s objects will be deterministically destructed, just as they would be in C++. However, the CLR doesn’t support deterministic destruction, preventing C# from providing this mechanism. Chapter 21 Automatic Memory Management (Garbage Collection) / Using Finalization to Release Native Resources Видимо, вы этого не читали - почитайте, это полезная книга. А IDisposable - вовсе не костыль, просто следует четко понимать разницу (касательно CLR) между освобождением ресурсов класса, и уничтожением самого экземпляра класса. Первая задача вполне управляема и детерминирована, вторая - неуправляема и недетерминирована (её выполняет GC). Даже если попытаться дернуть финализатор через рефлекшн (метод Finalize), это к освобождению памяти, заянтой под объект, не приведет. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 08:47 |
|
вопрос
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныChapter 21 Automatic Memory Management (Garbage Collection) / Using Finalization to Release Native Resources Видимо, вы этого не читали - почитайте, это полезная книга. Читал. До этого не мог понять зачем вообще надо IDisposable. С# пока изучаю, на С++ практики намного больше, а тут надо тупо помнить что пишется одинаково, а работает по-разному. Вот в чем мои претензии к синтаксису ~Class(). Не надо было теплое мягким называть, и проблем бы не было. Тут 18703950 я именно об этом писал, т.е. предположил, что Где-то в степи решил что ~Class() отработает как деструктор в С++ ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2016, 09:09 |
|
вопрос
|
|||
---|---|---|---|
#18+
Где-то в степи, Ха! А что будет, если переданный disposable в своей реализации не вызовет GC.SuppressFinalize, но будет иметь переопределенный Finalize? Кошмар! Это же страшное дело! ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2016, 15:03 |
|
вопрос
|
|||
---|---|---|---|
#18+
да ни чего не будет, если метод SuppressFinalize не будет вызвать в реализации Disposible, то объект просто будет поставлен в очередь на финализацию, а дальше уже зависит от реализации этого метода. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2016, 17:07 |
|
вопрос
|
|||
---|---|---|---|
#18+
Roman Mejtesда ни чего не будет, если метод SuppressFinalize не будет вызвать в реализации Disposible, то объект просто будет поставлен в очередь на финализацию, а дальше уже зависит от реализации этого метода. Не будет удален из очереди на финализацию. Ставится от в эту очередь при создании экземпляра, когда CLR видит у объекта финализатор. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2016, 17:09 |
|
|
start [/forum/topic.php?fid=20&fpage=68&tid=1400873]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
36ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 150ms |
0 / 0 |