Пустыя блокі ўловаў

Я часам працаваць у сітуацыі, калі мне трэба, каб злавіць выключэнне, калі ён калі-небудзь выкінутыя, але ніколі не рабіць нічога з ім. Іншымі словамі, выключэнне можа адбыцца, але гэта не мае значэння, калі ён робіць.

I recently read this article about a similar thing: http://c2.com/cgi/wiki?EmptyCatchClause

Гэты чалавек кажа пра тое, як каментарыю

// should never occur 

гэта код пах і ніколі не павінны з'яўляцца ў кодзе. Затым яны ідуць на растлумачыць, як каментар

// don't care if it happens

зусім розныя, і я бягу ў такіх сітуацыях, як гэта сам. Напрыклад, пры адпраўцы па электроннай пошце я зрабіць нешта падобнае на гэта:

var addressCollection = new MailAddressCollection();
foreach (string address in addresses)
{
    try
    {
        addressCollection.Add(address);
    }
    catch (Exception)
    {
       //Do nothing - if an invalid email occurs continue and try to add the rest
    }
}

Зараз, вы можаце думаць, што рабіць гэта дрэнная ідэя, так як вы хацелі б, каб вярнуцца да карыстача і растлумачыць, што адно або некалькі паведамленняў не можа быць адпраўлена атрымальніку. Але што, калі гэта проста адрас CC? Гэта менш важна, і вы ўсё роўна хочаце, каб адправіць паведамленне ў любым выпадку, нават калі адзін з гэтых адрасоў быў няверны (магчыма, проста памылка друку).

Так я права выкарыстоўваць пусты блок злавіць ці ёсць лепшая альтэрнатыва, што я не ведаю?

26
Нават калі мы выкажам здагадку, што мы не хвалюе, таму што электронная пошта з'яўляецца несапраўдным, гэта добра, каб увайсці выключэнне і прыняць да ведама несапраўдных электроннай пошты. Пустое выключэнне з'яўляецца толькі падставай для <�я> лянівы праграмавання.
дададзена аўтар Chibueze Opata, крыніца
Нават калі мы выкажам здагадку, што мы не хвалюе, таму што электронная пошта з'яўляецца несапраўдным, гэта добра, каб увайсці выключэнне і прыняць да ведама несапраўдных электроннай пошты. Пустое выключэнне з'яўляецца толькі падставай для <�я> лянівы праграмавання.
дададзена аўтар Chibueze Opata, крыніца
Я падазраю, што намер аўтара было тое, што каментар кажучы: «Гэтая памылка ніколі не павінна адбывацца» азначае, кадавальнік ня даў якой-небудзь думкі, што рабіць, калі памылка кідае выклік чаканням і адбываецца, так ці інакш. Другі каментарый «лепш», але яшчэ лепш, можна было б растлумачыць, <�я> чаму </я> вы не клапоціцеся пра памылку. У канчатковым рахунку, лепшы апрацоўкі выключэнняў залежыць ад таго, што ваша прыкладанне павінна рабіць. Глытаючы выключэнне без якіх-небудзь далейшых дзеянняў у парадку ў некаторых абставінах. У іншых, магчыма, неабходна ўвайсці спачатку, а ў некаторых, вы на самой справе трэба, каб паспрабаваць аднаўленне.
дададзена аўтар ThatBlairGuy, крыніца
Я падазраю, што намер аўтара было тое, што каментар кажучы: «Гэтая памылка ніколі не павінна адбывацца» азначае, кадавальнік ня даў якой-небудзь думкі, што рабіць, калі памылка кідае выклік чаканням і адбываецца, так ці інакш. Другі каментарый «лепш», але яшчэ лепш, можна было б растлумачыць, <�я> чаму </я> вы не клапоціцеся пра памылку. У канчатковым рахунку, лепшы апрацоўкі выключэнняў залежыць ад таго, што ваша прыкладанне павінна рабіць. Глытаючы выключэнне без якіх-небудзь далейшых дзеянняў у парадку ў некаторых абставінах. У іншых, магчыма, неабходна ўвайсці спачатку, а ў некаторых, вы на самой справе трэба, каб паспрабаваць аднаўленне.
дададзена аўтар ThatBlairGuy, крыніца
У вашым прыкладзе, я б да гэтага часу зрабіць што-то за выключэннем, хоць, нават проста яго рэгістрацыі - не можа нават даць карыстачу выбар аб тым, што <�я>, каб зрабіць з якія адмовілі адрасы электроннай пошты, але яго рэгістрацыі, так што вы <�я> ведаю, гэта адбылося, гэта таксама добра.
дададзена аўтар Arran, крыніца
У вашым прыкладзе, я б да гэтага часу зрабіць што-то за выключэннем, хоць, нават проста яго рэгістрацыі - не можа нават даць карыстачу выбар аб тым, што <�я>, каб зрабіць з якія адмовілі адрасы электроннай пошты, але яго рэгістрацыі, так што вы <�я> ведаю, гэта адбылося, гэта таксама добра.
дададзена аўтар Arran, крыніца
Як вы ведаеце, што Exception звязаны з CC-адрас, а не, напрыклад, да са стану памяці? як вы плануеце, каб акрыяць ад гэтага?
дададзена аўтар Zdeslav Vojkovic, крыніца
@ChibuezeOpata Я думаю, што вы маеце на ўвазе «прыклад» замест «апраўдання»
дададзена аўтар Nick Freeman, крыніца
@ChibuezeOpata Я думаю, што вы маеце на ўвазе «прыклад» замест «апраўдання»
дададзена аўтар Nick Freeman, крыніца
Дзякуй за каментары. Я згодны з вамі, што я павінен злавіць канкрэтныя выключэння ў дачыненні да фармату адрас і хай іншых тапырыцца. Я зраблю гэта змена
дададзена аўтар Serberuss, крыніца
Дзякуй за каментары. Я згодны з вамі, што я павінен злавіць канкрэтныя выключэння ў дачыненні да фармату адрас і хай іншых тапырыцца. Я зраблю гэта змена
дададзена аўтар Serberuss, крыніца

10 адказы

Вы цалкам маеце рацыю, каб выкарыстоўваць пусты блок злавіць, калі вы сапраўды хочаце, каб нічога не рабіць, калі пэўны тып выключэння адбываецца. Вы можаце палепшыць свой прыклад, ловячы толькі тыпы выключэнняў, якія вы чакаць адбыцца, і якія вы ведаеце, бяспечна ігнараваць. Пры лоўлі Exception , вы можаце схаваць памылкі і зрабіць яго больш цяжкім для сябе, каб адладзіць праграму.

Адна рэч, каб мець на ўвазе адносна апрацоўкі выключэнняў: ёсць вялікая розніца паміж выключэннямі, якія выкарыстоўваюцца для сігналізацыі стану памылкі знешнія па адносінах да праграмы, якая <�моцны> чакаецца адбывацца па меншай меры часам, і выключэнні, якія паказваюць памылка праграмавання. Прыклад 1 будзе выключэннем пра тое, што электронная пошта не можа быць дастаўлена, так як падлучэнне скончыўся, альбо выяву не можа быць захаваны, таму што не было месца на дыску. Прыклад 2 будзе выключэннем паказваючы, што вы спрабавалі перадаць няправільны тып аргументу метаду, ці што вы спрабавалі атрымаць доступ да элемента масіва за межы.

Для 2-га (памылка праграмавання), было б вялікай памылкай проста «праглынуць» выключэнне. Самае лепшае, што трэба зрабіць, гэта, як правіла, каб увайсці трасіроўкі стэка, а затым выскачыць паведамленне пра памылку, якое інфармуе карыстальніка, што адбылося ўнутраная памылка, і што яны павінны паслаць свае часопісы назад да распрацоўшчыкаў (гэта значыць вас). Або падчас распрацоўкі, вы можаце проста зрабіць яго раздрукаваць трасіроўкі стэка ў кансолі і збою праграмы.

Для 1-га (знешняя задача), няма ніякага правілы аб тым, што «права» рэч зрабіць. Гэта ўсё залежыць ад дэталяў прыкладання. Калі вы хочаце ігнараваць пэўныя ўмовы і працягнуць працу, то зрабіць гэта.

<�Моцны> НАОГУЛ:

It's good that you are reading technical books and articles. You can learn a lot from doing so. But please remember, as you read, you will find lots of advice from people saying that doing such-and-such a thing is always wrong or always right. Often these opinions border on religion. NEVER believe that doing things a certain way is absolutely "right" because a book or article (or an answer on SO... ) told you so. There are exceptions to every rule, and the people writing those articles don't know the details of your application. You do. Make sure that what you are reading makes sense, and if it doesn't, trust yourself.

64
дададзена
Я не згодны з вашай агульнай кропкі. Так, вы маеце рацыю, што гэта палягчае адладку, але ігнараванне ўловаў проста неакуратна праграмаванне і паказвае праграміст навыкі. Я ведаю, што ёсць тыя, хто гэтыя фанатыкі, калі Сапраўдныя члены прастора павінна ісці тут ці там, але лавіць усё выключэння проста добрае праграмаванне. Ёсць заўсёды вельмі рэдкія выключэнні, але вашы 1-ые прыклады выключэнняў, таксама павінны быць злоўлены, нават калі для ўваходу. Я хацеў бы ведаць, калі функцыя, якую я назваў не мог запісаць на дыск або адправіць па электроннай пошце, гэта дапамагло б мне вызначыць мой наступны курс дзеянняў для забеспячэння цэласнасці дадзеных.
дададзена аўтар Guy Park, крыніца
лол на тое, каб абсалютная сцвярджэнне аб абсалютных сцвярджэнняў.
дададзена аўтар Nick Freeman, крыніца
Вялікі пост дзякуй за інфармацыю. Я згодны з вашай апошняй кропкі, і я, хутчэй за ўсё, узяць на інфармацыі з апублікаванага крыніцы, а не блог або інтэрнэт-артыкуле.
дададзена аўтар Serberuss, крыніца

Вы цалкам маеце рацыю, каб выкарыстоўваць пусты блок злавіць, калі вы сапраўды хочаце, каб нічога не рабіць, калі пэўны тып выключэння адбываецца. Вы можаце палепшыць свой прыклад, ловячы толькі тыпы выключэнняў, якія вы чакаць адбыцца, і якія вы ведаеце, бяспечна ігнараваць. Пры лоўлі Exception , вы можаце схаваць памылкі і зрабіць яго больш цяжкім для сябе, каб адладзіць праграму.

Адна рэч, каб мець на ўвазе адносна апрацоўкі выключэнняў: ёсць вялікая розніца паміж выключэннямі, якія выкарыстоўваюцца для сігналізацыі стану памылкі знешнія па адносінах да праграмы, якая <�моцны> чакаецца адбывацца па меншай меры часам, і выключэнні, якія паказваюць памылка праграмавання. Прыклад 1 будзе выключэннем пра тое, што электронная пошта не можа быць дастаўлена, так як падлучэнне скончыўся, альбо выяву не можа быць захаваны, таму што не было месца на дыску. Прыклад 2 будзе выключэннем паказваючы, што вы спрабавалі перадаць няправільны тып аргументу метаду, ці што вы спрабавалі атрымаць доступ да элемента масіва за межы.

Для 2-га (памылка праграмавання), было б вялікай памылкай проста «праглынуць» выключэнне. Самае лепшае, што трэба зрабіць, гэта, як правіла, каб увайсці трасіроўкі стэка, а затым выскачыць паведамленне пра памылку, якое інфармуе карыстальніка, што адбылося ўнутраная памылка, і што яны павінны паслаць свае часопісы назад да распрацоўшчыкаў (гэта значыць вас). Або падчас распрацоўкі, вы можаце проста зрабіць яго раздрукаваць трасіроўкі стэка ў кансолі і збою праграмы.

Для 1-га (знешняя задача), няма ніякага правілы аб тым, што «права» рэч зрабіць. Гэта ўсё залежыць ад дэталяў прыкладання. Калі вы хочаце ігнараваць пэўныя ўмовы і працягнуць працу, то зрабіць гэта.

<�Моцны> НАОГУЛ:

It's good that you are reading technical books and articles. You can learn a lot from doing so. But please remember, as you read, you will find lots of advice from people saying that doing such-and-such a thing is always wrong or always right. Often these opinions border on religion. NEVER believe that doing things a certain way is absolutely "right" because a book or article (or an answer on SO... ) told you so. There are exceptions to every rule, and the people writing those articles don't know the details of your application. You do. Make sure that what you are reading makes sense, and if it doesn't, trust yourself.

64
дададзена
Я не згодны з вашай агульнай кропкі. Так, вы маеце рацыю, што гэта палягчае адладку, але ігнараванне ўловаў проста неакуратна праграмаванне і паказвае праграміст навыкі. Я ведаю, што ёсць тыя, хто гэтыя фанатыкі, калі Сапраўдныя члены прастора павінна ісці тут ці там, але лавіць усё выключэння проста добрае праграмаванне. Ёсць заўсёды вельмі рэдкія выключэнні, але вашы 1-ые прыклады выключэнняў, таксама павінны быць злоўлены, нават калі для ўваходу. Я хацеў бы ведаць, калі функцыя, якую я назваў не мог запісаць на дыск або адправіць па электроннай пошце, гэта дапамагло б мне вызначыць мой наступны курс дзеянняў для забеспячэння цэласнасці дадзеных.
дададзена аўтар Guy Park, крыніца
лол на тое, каб абсалютная сцвярджэнне аб абсалютных сцвярджэнняў.
дададзена аўтар Nick Freeman, крыніца
Вялікі пост дзякуй за інфармацыю. Я згодны з вашай апошняй кропкі, і я, хутчэй за ўсё, узяць на інфармацыі з апублікаванага крыніцы, а не блог або інтэрнэт-артыкуле.
дададзена аўтар Serberuss, крыніца

Пусты ўлоў блок выдатна у патрэбным месцы - хоць з вашага ўзору я б сказаў, вы павінны cetagorically <�моцны> НЕ выкарыстоўваць злавіць (Exception) . Замест гэтага вы павінны злавіць відавочнае выключэнне, што вы чакаеце, каб адбыцца.

Прычына гэтага заключаецца ў тым, што, калі вы глынаць ўсё, вы будзеце глынаць крытычныя дэфекты, якія вы не чакалі, таксама. Там цэлы свет розніцы паміж «Я не магу адправіць гэты адрас электроннай пошты» і «ваш кампутар знаходзіцца па-за дыскавай прасторы.» Вы не хочаце, каб працягваць спрабаваць адправіць наступныя 10000 лістоў, калі вы з дыскавай прасторы!

Розніца паміж «не павінна" і "не хвалюе, калі гэта адбудзецца», што, калі гэта «не павінна адбыцца», то, калі ён <�ет> робіць адбудзецца, вы не хочаце, каб праглынуць яго моўчкі! Калі гэта ўмова ніколі не чакаецца, адбудзецца, то, як правіла, каб прыкладанне да збою (ці, па меншай меры, спыніць чыста і ўвайсці багатае, што здарылася), так што вы можаце вызначыць гэта невыканальнае ўмова.

15
дададзена
Што ўзгадняюцца на «не павінна адбыцца». калі яны не адбудзецца, вы можаце зразумець, што вы клапоціцеся у рэшце рэшт.
дададзена аўтар Robert Kerr, крыніца
+1 для гэтага апошняга пункта. Памылкі, якія «не павінна адбыцца», маюць выдатную звычку насуперак чаканням і адбываецца ў любым выпадку. Асабліва пасля таго, як прыкладанне было вакол некаторы час і, магчыма, прайшлі праз некалькі змен.
дададзена аўтар ThatBlairGuy, крыніца

Пусты ўлоў блок выдатна у патрэбным месцы - хоць з вашага ўзору я б сказаў, вы павінны cetagorically <�моцны> НЕ выкарыстоўваць злавіць (Exception) . Замест гэтага вы павінны злавіць відавочнае выключэнне, што вы чакаеце, каб адбыцца.

Прычына гэтага заключаецца ў тым, што, калі вы глынаць ўсё, вы будзеце глынаць крытычныя дэфекты, якія вы не чакалі, таксама. Там цэлы свет розніцы паміж «Я не магу адправіць гэты адрас электроннай пошты» і «ваш кампутар знаходзіцца па-за дыскавай прасторы.» Вы не хочаце, каб працягваць спрабаваць адправіць наступныя 10000 лістоў, калі вы з дыскавай прасторы!

Розніца паміж «не павінна" і "не хвалюе, калі гэта адбудзецца», што, калі гэта «не павінна адбыцца», то, калі ён <�ет> робіць адбудзецца, вы не хочаце, каб праглынуць яго моўчкі! Калі гэта ўмова ніколі не чакаецца, адбудзецца, то, як правіла, каб прыкладанне да збою (ці, па меншай меры, спыніць чыста і ўвайсці багатае, што здарылася), так што вы можаце вызначыць гэта невыканальнае ўмова.

15
дададзена
Што ўзгадняюцца на «не павінна адбыцца». калі яны не адбудзецца, вы можаце зразумець, што вы клапоціцеся у рэшце рэшт.
дададзена аўтар Robert Kerr, крыніца
+1 для гэтага апошняга пункта. Памылкі, якія «не павінна адбыцца», маюць выдатную звычку насуперак чаканням і адбываецца ў любым выпадку. Асабліва пасля таго, як прыкладанне было вакол некаторы час і, магчыма, прайшлі праз некалькі змен.
дададзена аўтар ThatBlairGuy, крыніца

Калі выключэнне не павінна быць кінута, то няма ніякага сэнсу лавіць яго - яно ніколі не павінна здарыцца, і калі яно вам трэба ведаць аб гэтым.

Калі ёсць канкрэтныя сцэнары, якія могуць выклікаць збой, што вы добра з, то вы павінны злавіць і тэст для тых канкрэтных сцэнарыяў і паўторна выдаць ва ўсіх іншых выпадках, напрыклад,

foreach (string address in addresses)
{
    try
    {
        addressCollection.Add(address);
    }
    catch (EmailNotSentException ex)
    {
        if (IsCausedByMissingCcAddress(ex))
        {
           //Handle this case here e.g. display a warning or just nothing
        }
        else
        {
            throw;
        }
    }
}

Варта адзначыць, што прыведзены вышэй код перахапляе спецыфічныя (калі выдуманыя) хутчэй выключэнне, чым лавіць Exception . Я магу думаць аб некалькіх выпадках, калі ён з'яўляецца законным, каб злавіць Exception у адрозненне ад лоўлі некаторага пэўнага тыпу выключэння, які вы чакаеце, каб быць выкінутыя.

7
дададзена
@Serberuss Так - злавіць найбольш канкрэтнае выключэнне, якое вы можаце
дададзена аўтар Justin, крыніца
@DanPuzey Дзякуй
дададзена аўтар Justin, крыніца
Ваш кінуць , верагодна, варта ў яшчэ блок ...
дададзена аўтар Dan Puzey, крыніца
Я разумею, што вы кажаце. Я мяркую, што ваша EmailNotSendException ідэя аб тым, што выключэння, звязаныя з няправільным адрасам электроннай пошты згрупаваныя тут?
дададзена аўтар Serberuss, крыніца

Калі выключэнне не павінна быць кінута, то няма ніякага сэнсу лавіць яго - яно ніколі не павінна здарыцца, і калі яно вам трэба ведаць аб гэтым.

Калі ёсць канкрэтныя сцэнары, якія могуць выклікаць збой, што вы добра з, то вы павінны злавіць і тэст для тых канкрэтных сцэнарыяў і паўторна выдаць ва ўсіх іншых выпадках, напрыклад,

foreach (string address in addresses)
{
    try
    {
        addressCollection.Add(address);
    }
    catch (EmailNotSentException ex)
    {
        if (IsCausedByMissingCcAddress(ex))
        {
           //Handle this case here e.g. display a warning or just nothing
        }
        else
        {
            throw;
        }
    }
}

Варта адзначыць, што прыведзены вышэй код перахапляе спецыфічныя (калі выдуманыя) хутчэй выключэнне, чым лавіць Exception . Я магу думаць аб некалькіх выпадках, калі ён з'яўляецца законным, каб злавіць Exception у адрозненне ад лоўлі некаторага пэўнага тыпу выключэння, які вы чакаеце, каб быць выкінутыя.

7
дададзена
@Serberuss Так - злавіць найбольш канкрэтнае выключэнне, якое вы можаце
дададзена аўтар Justin, крыніца
@DanPuzey Дзякуй
дададзена аўтар Justin, крыніца
Ваш кінуць , верагодна, варта ў яшчэ блок ...
дададзена аўтар Dan Puzey, крыніца
Я разумею, што вы кажаце. Я мяркую, што ваша EmailNotSendException ідэя аб тым, што выключэння, звязаныя з няправільным адрасам электроннай пошты згрупаваныя тут?
дададзена аўтар Serberuss, крыніца

Многія з іншых адказаў, даюць добрыя прычыны, калі гэта было б добра, каб злавіць выключэнне, аднак многія дапаможныя класы спосабаў ня кідаць выключэння на ўсіх.

Часта гэтыя метады будуць мець прэфікс Паспрабуйце перад імі. Замест таго, каб кідаць выключэнне функцыя вяртае лагічнае значэнне, якое паказвае, калі задача паспяхова.

A good example of this is Parse vs TryParse

string s = "Potato";
int i;
if(int.TryParse(s, out i))
{
    //This code is only executed if "s" was parsed succesfully.
    aCollectionOfInts.Add(i);
}

Калі вы спрабуеце вышэйпаказаную функцыю ў цыкле і параўнаць яго з Parse + Catch equilvilant метад TryParse будзе нашмат хутчэй.

5
дададзена
Так, дрэнны карыстацкі ўвод не з'яўляецца выключным выпадкам, гэта чаканы выпадак. Людзі не так прадказальныя, як кампутары. Кінуўшы выключэнне ў дадзеным выпадку, мне здаецца, каб быць
дададзена аўтар Nick Freeman, крыніца
Ўзгоднены Я вельмі люблю па метадах Try
дададзена аўтар Serberuss, крыніца

Многія з іншых адказаў, даюць добрыя прычыны, калі гэта было б добра, каб злавіць выключэнне, аднак многія дапаможныя класы спосабаў ня кідаць выключэння на ўсіх.

Часта гэтыя метады будуць мець прэфікс Паспрабуйце перад імі. Замест таго, каб кідаць выключэнне функцыя вяртае лагічнае значэнне, якое паказвае, калі задача паспяхова.

A good example of this is Parse vs TryParse

string s = "Potato";
int i;
if(int.TryParse(s, out i))
{
    //This code is only executed if "s" was parsed succesfully.
    aCollectionOfInts.Add(i);
}

Калі вы спрабуеце вышэйпаказаную функцыю ў цыкле і параўнаць яго з Parse + Catch equilvilant метад TryParse будзе нашмат хутчэй.

5
дададзена
Так, дрэнны карыстацкі ўвод не з'яўляецца выключным выпадкам, гэта чаканы выпадак. Людзі не так прадказальныя, як кампутары. Кінуўшы выключэнне ў дадзеным выпадку, мне здаецца, каб быць
дададзена аўтар Nick Freeman, крыніца
Ўзгоднены Я вельмі люблю па метадах Try
дададзена аўтар Serberuss, крыніца

Выкарыстанне пустога блока злавіць проста праглыне выключэнне, я заўсёды з гэтым справіцца, нават калі яна далажыць вам, што Exception адбыўся.

Акрамя лаўлю радавога Exception дрэнная практыка ў сувязі з тым, што можа схаваць памылкі ў дадатку. Напрыклад, вы можаце ўлавілі ArgumentOutOfRange выключэнне, якое вы не разумелі, што адбываецца, а затым праглынуў яго (г.зн. нічога не зрабіў з ім).

2
дададзена

Выкарыстанне пустога блока злавіць проста праглыне выключэнне, я заўсёды з гэтым справіцца, нават калі яна далажыць вам, што Exception адбыўся.

Акрамя лаўлю радавога Exception дрэнная практыка ў сувязі з тым, што можа схаваць памылкі ў дадатку. Напрыклад, вы можаце ўлавілі ArgumentOutOfRange выключэнне, якое вы не разумелі, што адбываецца, а затым праглынуў яго (г.зн. нічога не зрабіў з ім).

2
дададзена