tag:blogger.com,1999:blog-5422036137568788209.post2867357403577166971..comments2023-02-28T12:04:19.260+03:00Comments on handcode: Раcширяем IDisposableИлья Дубаденкоhttp://www.blogger.com/profile/03756815679135463187noreply@blogger.comBlogger30125tag:blogger.com,1999:blog-5422036137568788209.post-21302959977180288562010-07-26T17:19:29.916+04:002010-07-26T17:19:29.916+04:002dogwatch:
Вставил свой код в студию, компилирует...2dogwatch:<br /><br />Вставил свой код в студию, компилируется и работает нормально. Что я делаю не так?eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-4172842969976467262010-07-24T12:16:38.489+04:002010-07-24T12:16:38.489+04:00@Omari
Совершенно с Вам согласен с тем, что зануле...@Omari<br />Совершенно с Вам согласен с тем, что занулением должен заниматься владелец объекта. Вот только хотелось бы придумать красивый путь зануления через extention-метод (похоже такого решения не существует). Но пока занулять можно явно присвоить null или через Helper-метод.Илья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-77713190065787747682010-07-23T20:34:27.494+04:002010-07-23T20:34:27.494+04:00@zhe
тип должен совпадать. иначе ошибка компиляции...@zhe<br />тип должен совпадать. иначе ошибка компиляцииUnknownhttps://www.blogger.com/profile/13032885525649119313noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-44349950634440007112010-07-23T19:37:28.694+04:002010-07-23T19:37:28.694+04:00"Мне кажется, что присвоить ссылке null после..."Мне кажется, что присвоить ссылке null после вызова Dispose - это хороший тон"<br />По моему ясней, когда это явно делает объект - владелец ссылки. К тому же он еще и отвечает за время жизни объекта.<br />А так получается, что ссылка вдруг обнулилась и слово "Safe" не вносит ясности. Может "DisposeAndNullify"?OmariOhttps://www.blogger.com/profile/15742544005513676789noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-12895551715555559592010-07-23T12:57:56.692+04:002010-07-23T12:57:56.692+04:00dogwatch, "if ( null != self )" - Йода-к...dogwatch, "if ( null != self )" - Йода-код детектед )))eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-11160147404994580092010-07-23T12:56:43.110+04:002010-07-23T12:56:43.110+04:00dogwatch, это почему это мой вариант не будет рабо...dogwatch, это почему это мой вариант не будет работать?eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-26171824026150690212010-07-23T10:03:58.148+04:002010-07-23T10:03:58.148+04:00@Илья Дубаденко
Мне кажется, что присвоить ссылке ...@Илья Дубаденко<br />Мне кажется, что присвоить ссылке null после вызова Dispose - это хороший тон.<br /><br />Мне почему то думается что не совсем это хорошая идея.<br /><br />Давайте посмотрим на пару IDisposable классов.<br />1. Stream<br />После Dispose можно проверить CanRead, CanWrite<br />2. SqlConnection<br />После Dispose можно проверить ConnectionState.<br />Причем соединение может закрыться и до вызова Dispose. Так что в любом случае нужно обрабатывать ошибки.<br />3. SerialPort<br />После Dispose можно проверить IsOpen<br />И порт может независимо от нас закрыться. Например зависнит подключеный к COM порту GSM модем (стандартная ситуация).<br /><br /><br />Ну и такое. <br />Например если мы реализуем пул соединений, то вызов Dispose() на конкретном соединении из пула просто вернет его в пул.<br /><br />Мне кажется за Dispose нужно программисту следить. <br />А то получается мы хотим сдлать деструктор. <br /><br />В итоге на мой взгляд лучший вариант, если уж очень хочется занулить объект после Dispose это:<br />some.SafeDispose();<br />some = null;Vadim Sentyaevhttps://www.blogger.com/profile/05869650933473392829noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-50736758270751696132010-07-23T03:43:53.031+04:002010-07-23T03:43:53.031+04:00@zhe
вариант с ref object работать не будет.
можно...@zhe<br />вариант с ref object работать не будет.<br />можно так:<br />static public void SafeDisposeAndNull(ref T self) where T : class, IDisposable {<br /> if ( null != self ) { <br /> self.Dispose(); <br /> self = null; <br /> } <br />} <br />;)Unknownhttps://www.blogger.com/profile/13032885525649119313noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-55001005479892745392010-07-23T01:48:10.055+04:002010-07-23T01:48:10.055+04:00Что мешает писать:
using (some) {}
в качестве бе...Что мешает писать:<br /><br />using (some) {}<br /><br />в качестве безопасного Dispose?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-2191036552079520022010-07-23T00:04:29.190+04:002010-07-23T00:04:29.190+04:00Мне кажется, что присвоить ссылке null после вызов...Мне кажется, что присвоить ссылке null после вызова Dispose - это хороший тон.Илья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-22533048376520184132010-07-22T23:55:48.868+04:002010-07-22T23:55:48.868+04:00Насколько я помню, под MDX еще имеет смысл проверя...Насколько я помню, под MDX еще имеет смысл проверять IsDisposed или то-то вроже этого.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-37859059319143857612010-07-22T23:54:41.980+04:002010-07-22T23:54:41.980+04:00@Omari
Safe относительно NullReferenceException.
Н...@Omari<br />Safe относительно NullReferenceException.<br />Например, если some=null, то some.SafeDispose(); отработает нормально, и проверка на null не нужна.Илья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-38852982122504940842010-07-22T23:48:06.992+04:002010-07-22T23:48:06.992+04:00Почему называется safe?
Thread safe диспоузинга вр...Почему называется safe?<br />Thread safe диспоузинга вроде нет.OmariOhttps://www.blogger.com/profile/15742544005513676789noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-39304251053457866212010-07-22T23:19:27.881+04:002010-07-22T23:19:27.881+04:00Я читал на codeproject статейку, в которой индийск...Я читал на codeproject статейку, в которой индийский программист призывал всех создавать строки DataRow примерно таким способом:<br />using(DataRow row = table.NewRow()){<br /> //тут строка заполняется значениями<br /> table.Rows.Add(row);<br />}<br />потом идет работа с таблицей...<br />И ведь работает, к сожалению... А тот программист был уверен что это очень наглядный пример использования IDisposableAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-74673469600319214862010-07-22T19:23:12.320+04:002010-07-22T19:23:12.320+04:00Vadim Sentyaev, рассуждаете правильно. Но язык раз...Vadim Sentyaev, рассуждаете правильно. Но язык разрешает это делать. Ничего не поделаешь )))eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-43538239560669962062010-07-22T18:49:28.003+04:002010-07-22T18:49:28.003+04:00Походу у меня знаний не хватает...
using (Some so...Походу у меня знаний не хватает...<br /><br />using (Some some = new Some()) {}<br />разворачивается на:<br />Some some = new Some()<br />try<br />{<br />...<br />}<br />finally<br />{<br />((IDisposable)some).Dispose();<br />}<br /><br />Тогда в зачем использовать <br />Some some;<br />using (some = new Some()) { ... }<br />или<br />Some some = new Some();<br />using (some) { ... }<br /><br />Ведь в любом случае после блока using к переменным нельзя обращаться, они уже как-бы "уничтожены", ну или если это применить к Stream, то он может быть закрыть.Vadim Sentyaevhttps://www.blogger.com/profile/05869650933473392829noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-21538774648412787442010-07-22T18:36:10.507+04:002010-07-22T18:36:10.507+04:00Или даже так :)
Some some = new Some();
using (s...Или даже так :)<br /><br />Some some = new Some();<br />using (some) { ... }eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-62618588493473572022010-07-22T18:25:11.525+04:002010-07-22T18:25:11.525+04:00Бывает даже так:
Some some;
using (some = new Some...Бывает даже так:<br />Some some;<br />using (some = new Some()) { ... }Илья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-24437614820875107762010-07-22T18:21:59.251+04:002010-07-22T18:21:59.251+04:00Vadim Sentyaev, согласен. С using вообще не надо г...Vadim Sentyaev, согласен. С using вообще не надо городить весь огород с проверками, обнулениями и т. д.<br /><br />Автор видать имеет в виду примеры, когда using использовать низя. Например, если создание объекта происходит в одном месте, а его уничтожение - вообще хрен знает где :)<br />Бывают и такие ситуации.eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-78943810666872487132010-07-22T18:19:05.827+04:002010-07-22T18:19:05.827+04:00zhe:
Это да.
С другой стороны есть
using (Some s...zhe:<br />Это да. <br />С другой стороны есть <br />using (Some some = new Some()) {}<br />а далее к нему уже не обратишься.Vadim Sentyaevhttps://www.blogger.com/profile/05869650933473392829noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-13129046074374835372010-07-22T18:16:51.394+04:002010-07-22T18:16:51.394+04:00@zhe
В идеале конечно же надо ловить ObjectDispose...@zhe<br />В идеале конечно же надо ловить ObjectDisposedException, но когда объект null , все сомнения в том, что объект еще можно использовать отпадают).<br /><br />@Vadim Sentyaev<br />Но все-таки главная идея избавиться от проверки на null.<br /><br />В качестве бонуса можно добавить свой код pre/post код перед/после Dispose:<br />public static void MyDispose(this IDisposable self)<br />{<br />if (self != null)<br />{<br />// pre-code<br />self.Dispose();<br />// post-code<br />}<br />}Илья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-48133710379854186192010-07-22T18:09:49.913+04:002010-07-22T18:09:49.913+04:002Vadim Sentyaev:
теоретически возможна ситуация, к...2Vadim Sentyaev:<br />теоретически возможна ситуация, когда вы сможете попытаться вызвать метод уже диспоузнутого экземпляра. И этот метод может даже успешно выполниться :)<br />Видимо автор занулением some пытается избежать таких ситуаций и сделать код более робустным ))<br /><br />Лучше, если вызов такого метода упадёт по NullReferenceException, нежели выполнится.eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-89441479405013264772010-07-22T17:57:30.644+04:002010-07-22T17:57:30.644+04:00Что-то я не пойму, зачем занулять some?
Ведь посл...Что-то я не пойму, зачем занулять some? <br />Ведь после того как мы вызвали Dispose, это уже не мы заботимся о переменной, а сборщик мусора. <br /><br />По идее для нас Dispose фактически тоже самое, что и уничтожение объекта, и далее его использовать нельзя.Vadim Sentyaevhttps://www.blogger.com/profile/05869650933473392829noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-68165807962985148202010-07-22T17:34:04.113+04:002010-07-22T17:34:04.113+04:00Опять накосячил ))))) Должно быть так:
DisposeHe...Опять накосячил ))))) Должно быть так:<br /><br />DisposeHelper.SafeDisposeAndNull(ref some);eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-2180739952908063652010-07-22T17:30:49.044+04:002010-07-22T17:30:49.044+04:00Упс. Накосячил с использованием. :) Должно быть та...Упс. Накосячил с использованием. :) Должно быть так.<br /><br />DisposeHelper.SafeDispose(ref some);eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.com