Použitím neošetřené výjimky namísto Obsahuje ()?

hlasů
6

Představte si, že objekt, který pracuje s má sbírku jiné objekty s ním spojené, například kolekci ovládacích prvků WinForm. Chcete-li zjistit o určitém objektu v kolekci, ale sbírka nemá Contains()metodu. Existuje několik způsobů, jak se vypořádat s tím.

  • Implementovat vlastní Contains()metodu smyčkou přes všechny položky v kolekci naleznete, pokud jeden z nich je to, co hledáte. To se zdá být „best practice“ přístup.
  • Nedávno jsem narazil na určité číslo, kde namísto smyčky, došlo k pokusu o přístup k objektu uvnitř příkazu try, a to následovně:
try  
{  
    Object aObject = myCollection[myObject];  
}  
catch(Exception e)  
{  
    //if this is thrown, then the object doesn't exist in the collection
}

Moje otázka je, jak chudé programovací praxe považujete druhou možnost byl a proč? Jak je výkon ní ve srovnání s smyčky prostřednictvím kolekce?

Položena 12/08/2008 v 00:49
zdroj uživatelem
V jiných jazycích...                            


8 odpovědí

hlasů
4

Obecným pravidlem je, aby se zabránilo používání výjimky pro řízení toku, pokud okolnosti, které vyvolá výjimku jsou „výjimečné“ - například velmi vzácné!

Pokud je to něco, co se stane, normálně a pravidelně rozhodně by nemělo být nakládáno jako výjimku.

Výjimky jsou velmi, velmi pomalu kvůli všem režie spojená, takže tam může být výkonnostní důvody i v případě, že se to děje dost často.

Odpovězeno 12/08/2008 v 01:30
zdroj uživatelem

hlasů
2

Já bych si říci, že to je docela špatná praxe. Zatímco někteří lidé mohou být rádi, že průchozí kolekce je méně účinný pro vyvolání výjimky, je zpětný k vyvolání výjimky. Chtěl bych také otázku, proč používáte kolekci přistupovat položku klíčem, když by bylo vhodnější používat slovník nebo Hashtable.

Můj hlavní problém s tímto kódem však je, že bez ohledu na typ vyvolána výjimka, jste vždy bude vlevo se stejným výsledkem.

Například výjimka by mohla být vyvolána, protože objekt neexistuje ve sbírce, nebo proto, že sbírka je sám o sobě null, nebo proto, že nemůžete házet myCollect [myObject] pro aObject.

Všechny tyto výjimky dostane zacházeno stejným způsobem, který nemusí být váš záměr.

Jedná se o několik pěkných článků o tom, kdy a kde je to považováno za přijatelné usally hodit výjimky:

Zejména se mi líbí tento citát z druhého článku:

Je důležité, že výjimky jsou vyvolána pouze v případě, kdy dojde k neočekávané nebo neplatné aktivity, které brání metodu dokončení jeho normální funkci. Zpracování výjimek představuje malou režii a snižuje výkon, takže by neměl být používán k normálnímu běhu programu namísto podmíněné zpracování. To může také být obtížné udržovat kód, který zneužívá zpracování výjimek tímto způsobem.

Odpovězeno 12/08/2008 v 01:26
zdroj uživatelem

hlasů
1

Výjimky by měly být výjimečné.

Něco jako ‚Sběr chybí, protože databáze klesla z pod něj‘ je výjimečná

Něco jako ‚klíč není k dispozici‘ je normální chování pro slovníku.

Pro tento konkrétní příklad kolekce WinForms Control je Controlsvlastnost má ContainsKeymetodu, která je to, co jste měl použít.

Neexistuje ContainsValueproto, že pokud se jedná o slovníky / hashtables, neexistuje žádný rychlý způsob, jak krátký iterace celé kolekce, kontrolovat, jestli je něco, co je přítomen, takže jste skutečně odradit od toho, aby.

Co se týče PROČ Výjimky by měly být výjimečné, je to o 2 věci

  1. Indikuje to, co váš kód se snaží dělat. Chcete-li mít svůj kód odpovídají tomu, co se snaží dosáhnout, tak přesně, jak je to možné, takže je čitelný a udržovatelný. Zpracování výjimek přidává spoustu možností cruft který dostane v cestě tomuto účelu

  2. Krátkost kódu. Chcete, aby váš kód dělat to, co to dělá v nejpřímější cestou, takže je čitelný a udržovatelný. Opět platí, že Cruft přidal zpracování výjimek dostane do cesty tohoto.

Odpovězeno 12/08/2008 v 03:02
zdroj uživatelem

hlasů
0

Podívejte se na tomto blogu od Krzystof: http://blogs.msdn.com/kcwalina/archive/2008/07/17/ExceptionalError.aspx

Výjimky by měly být použity pro komunikaci chybové stavy, ale neměly by být používány jako řídící logiky (zvláště když tam je daleko jednodušší způsoby, jak zjistit stav, jako je například obsahuje).

Součástí problému je, že výjimky, aniž by nákladné hodit jsou drahé zachytit i všechny výjimky jsou chyceni v určitém okamžiku.

Odpovězeno 17/08/2008 v 15:38
zdroj uživatelem

hlasů
0

Obecně platí, že s použitím zpracování výjimek pro tok programu a logika je špatná praxe. Osobně se domnívám, že tato možnost je nepřijatelná využívání výjimek. S ohledem na vlastnosti jazyků běžně používané v těchto dnech (například LINQ a lambd v jazyce C #, například) neexistuje žádný důvod, proč psát svůj vlastní způsob obsahuje ().

Jako poslední myšlenka, v dnešní době většina sbírky dělat mají obsahuje metodu již. Takže myslím, že ve většině případů se jedná o non-záležitost.

Odpovězeno 12/08/2008 v 01:10
zdroj uživatelem

hlasů
0

Musel bych o tom přemýšlet více o tom, jak moc se mi to líbí ... můj instinkt je, eh, ne tolik ...

EDIT: komentáře Ryan Fox má na výjimečném případě je perfektní, souhlasím

Pokud jde o výkon, záleží na indexovací o shromažďování. C # vám umožní přepsat operátor indexovací, takže pokud to dělá smyčku for stejně jako obsahuje metodu, kterou by se napsat, pak to bude stejně pomalá (s možná pár nanosekund pomalejší kvůli try / catch ... ale nic obávat, pokud tento kodex sám o sobě je v obrovské smyčky).

V případě, že indexování je O (1) (nebo dokonce O (log (n)) ... nebo něco rychleji než O (n)), pak se roztok / catch try by být rychlejší samozřejmě.

Také já jsem za předpokladu, že indexovací hází výjimku, pokud se vrací null, můžete samozřejmě jen zkontrolovat neplatné a nelze použít try / catch.

Odpovězeno 12/08/2008 v 01:07
zdroj uživatelem

hlasů
0

Pokud se při psaní kódu, můžete očekávat, že tento objekt bude ve sbírce, a pak za běhu zjistíte, že tomu tak není, tak bych zavolat, že výjimečný případ, a tak je třeba použít výjimku.

Nicméně, pokud jste prostě testování pro existenci objektu, a vy zjistíte, že tam není, to není výjimečné. Používání výjimku v tomto případě není vhodné.

Analýza výkonnosti běhového závisí na aktuální kolekci jsou použity, a tato metoda by hledal to. To by nemělo záležet ačkoli. Nedovolte, aby iluze optimalizace zmást do psaní matoucí kódu.

Odpovězeno 12/08/2008 v 01:01
zdroj uživatelem

hlasů
-2

Ta je přijatelné řešení. I když bych určitě chytit na specifické výjimky (ElementNotFound?), Že sbírka vrhá v této věci.

Speedwise, záleží na společné věci. Pokud máte větší šanci najít prvek, než ne, bude řešení výjimka být rychlejší. Pokud jste s větší pravděpodobností k selhání, pak to bude záviset na velikosti odběru a jeho rychlost iterace. Ať tak či onak, kterou chcete měřit proti normálním používání, aby zjistil, jestli je to vlastně bottle neck před starostí o rychlosti, jako je tento. Jít pro přehlednost první a druhé řešení je mnohem jasnější než první.

Odpovězeno 12/08/2008 v 01:03
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more