1. Nahradiť prístupné polia atribútmi
1、. .NET dátové viazanie podporuje iba viazanie dát a výhody viazania dát môžete získať použitím atribútov. 2. Pri získaní a nastavení prístupu k vlastnosti môžete použiť zámok na pridanie podpory viacvláknového spracovania.
2. readonly (konštanta za behu) a const (konštanta času kompilácie)
1. const môže byť použitý len pre primitívne typy, enumy a reťazce, zatiaľ čo readonly môže byť akýkoľvek typ; 2. Const bude pri kompilácii nahradený konkrétnou konštantou, takže ak sa v referencii použijú hodnoty const aj readonly hodnoty, zmena na readonly zmení pôvodný zámer návrhu, ktorým je potreba prekompilovať zmenenú zostavu na referenciu na novú konštantnú hodnotu. 3. Const je efektívnejší ako len na čítanie, ale stráca flexibilitu aplikácie.
3. IS a AS
1. Oba sú prevodmi typov za behu, keďže operátory môžu byť použité len v typoch referencií, zatiaľ čo is môže používať hodnoty a typy referencií; 2. Bežná prax je použiť IS na určenie typu a potom zvoliť použitie ako alebo silného operátora konverzie typov (konverziu definovanú operátorom) selektívne.
4. Podmienený atribút namiesto #if #endif条件编译
1. PodmienenýAtribút sa používa iba na úrovni metódy a iné položky ako typy, atribúty a podobne sú neplatné. A #if #endif则不受此限制; 2. PodmienenýAtribút môže pridať viacero operácií OR (OR) pre kompilačné podmienky a #if #endif则可以添加与(AND) [tu môže byť úplne definovaný ako ďalší samostatný symbol]; 3. Definíciu ConditioanlAttribute možno použiť samostatnou metódou, aby bol program flexibilnejší.
5. Poskytnúť metódu ToString()
1. Môže poskytovať používateľom podrobnejšie informácie priateľskejším spôsobom; 2. Použiť metódu IFormatter.ToString() na flexibilnejšie prispôsobenie, a ak pridáte rozhrania IFormatProvider a ICustomFormatter, bude dávať väčší zmysel prispôsobiť výstup správy.
6. Rozdiel medzi hodnotou a typom referencie
1. Typy hodnôt nepodporujú polymorfizmus, ktorý je vhodný na ukladanie dát ovládaných aplikáciami, zatiaľ čo referencie podporujú polymorfizmus, ktorý je vhodný na definovanie správania aplikácií. 2. Pre polia definované ako hodnotové typy je možné výrazne zlepšiť výkon programu; 3. Typ hodnoty má menej fragmentácie pamäte haldy, pamäťového odpadu a času nepriameho prístupu, a jeho návrat v metóde sa vykonáva vo forme replikácie, aby sa zabránilo vystaveniu vnútornej štruktúry vonkajšiemu svetu. 4. Typy hodnôt sa používajú v nasledujúcich scenároch: Zodpovednosti typov sa primárne používajú na ukladanie dát; Verejné rozhrania sú úplne definované niektorými atribútmi prístupu členov dát; Podtriedy nikdy neexistujú; Nikdy neexistuje polymorfné správanie.
7. Typy hodnôt by mali byť implementované ako konštantné a atómové typy, čo je to možné
1. Uľahčiť písanie a údržbu kódu; 2. Tri stratégie inicializácie konštánt: pri konštrukcii; rastlinná metóda; Vytvorte mutabilnú pomocnú triedu (napr. StringBuilder).
8. Zabezpečiť, aby 0 bola hodná platného statusu
1. Predvolený stav typu hodnoty by mal byť 0; 2. 0 enum typu by nemalo byť neplatné; V atribúte Flags má zabezpečiť, že hodnota 0 je platný stav; 3. Keď je reťazec prázdny, reťazec môže byť vrátený. prázdny reťazec pre prázdny.
9. Vzťahy viacerých reprezentácií rovnakého súdu
1. ReferenceEquals() určuje, že referencie sú rovnaké, a musí to byť pravda, keď obe odkazujú na ten istý objekt. 2. Statická metóda Equals() sa používa najprv na referenčné posúdenie a potom na posúdenie typu hodnoty; 3. Na posúdenie typu referencie môžete použiť metódu prepísania Equals() pri použití sémantiky hodnôt. 4. Pri prepisovaní metódy Equals() by sa mala prepísať aj metóda GetHashCode() a súčasne by mala byť poskytnutá operácia operátor==().
10. Pochopenie nedostatkov metódy GetHashCode()
1. GetHashCode() sa aplikuje iba na hashovacie hodnoty hashovaných ** definovaných kľúčov, ako sú HashTable alebo Dictionary; 2. GetHashCode() by mal dodržiavať príslušné tri pravidlá: dva rovnaké objekty by mali vracať rovnaký hash kód; by mala byť inštancia invariantná; Hašovacia funkcia by mala generovať náhodné rozdelenie naprieč všetkými celými číslami.
11. Uprednostniť použitie príkazov foreach loop
1. foreach môže eliminovať kontrolu kompilátora na hranici poľa v for slučke; 2. Kruhová premenná foreach je iba na čítanie a existuje explicitná transformácia, ktorá vyhodí výnimku, keď je typ objektu ** nesprávny; 3. ** potrebné na použitie foreach je: mať verejnú metódu GetEnumberator(); Rozhranie IEnumberable je explicitne implementované. Je implementované rozhranie IEnumerator; 4. foreach môže priniesť výhody správy zdrojov, pretože ak kompilátor dokáže určiť IDizposable rozhranie, môže použiť optimalizované try... nakoniec blok;
12. Inicializácia predvoleného poľa je lepšia ako príkaz priradenia
1. Životnosť poľa inicializuje typ hodnoty na 0 a referenčný typ na null. 2. Opakovaná inicializácia toho istého objektu zníži efektivitu vykonávania kódu. 3. Vloženie inicializácie poľa do konštruktora prispieva k spracovaniu výnimiek.
13. Použiť statický konštruktér na inicializáciu statických členov
1. Statický konštruktér sa vykoná pred prístupom k akejkoľvek metóde, premennej alebo atribútu triedy; 2. Statické polia tiež bežia pred statickým konštruktorom a statický konštruktér je vhodný na spracovanie výnimiek.
14. Použite reťazec konštruktorov (v. NET 4.0 už tento problém rieši s voliteľnými parametrami)
1. Použiť to na odovzdanie inicializačnej práce inému konštruktorovi a použiť bázu na volanie konštruktora základnej triedy; 2. Sekvencia operácií typových inštancií je: nastaviť všetky statické polia na 0; Vykonávanie inicializátorov statického poľa; statický konštruktor, ktorý vykonáva základnú triedu; Statické konštruktéry, ktoré vykonávajú aktuálny typ; Nastavte všetky inštancie polia na 0; Inicializátory inštancie poľa; Spustiť príslušný konštruktor inštancie základnej triedy; Spustiť inštanciu konštruktora aktuálneho typu.
15. Použitie príkazov using a try/finally na vyčistenie zdrojov
V metóde Dispose() rozhrania IDisposable je možné GC.SuppressFinalize() použiť na upozornenie garbage collectoru, že posledná operácia už nie je vykonaná.
16. Minimalizujte pamäťový odpad
1. Vyžaduje dodatočný čas procesora na alokáciu a zničenie objektov na halde; 2. Techniky na zníženie počtu priradených objektov: často používané lokálne premenné sú propagované do polí; Poskytuje triedu, ktorá uchováva bežné inštancie Singleton objektov, ktoré vyjadrujú špecifické typy. 3. Použite StringBuilder na vykonávanie zložitých operácií s reťazcami.
17. Minimalizovať balenie a vykladanie
1. Venovať pozornosť implicitnej konverzii typu na System.Object, pričom hodnotový typ by nemal byť nahradený typom System.Object; 2. Použitie rozhraní namiesto typov môže zabrániť boxingu, teda implementácii hodnotových typov z rozhraní a následnému volaniu členov cez rozhrania.
18. Implementovať štandardný režim Likvidácia
1. Na použitie nepamäťových zdrojov musí mať finalizer, garbage collector pridá implementované objekty finalizera do terminačnej fronty po dokončení pamäťových objektov, ktoré ich ešte neukončili, a potom garbage collector spustí nové vlákno na spustenie finalizerov na týchto objektoch. Týmto sa môže predísť problému úniku pamäte spôsobenému neuvoľňovaním nespravovaných pamäťových zdrojov. 2. Použitie metódy IDisposable.dispose() vyžaduje štyri aspekty práce: uvoľnenie všetkých nespravovaných zdrojov; Uvoľniť všetky spravované zdroje; Nastavte stavový marker, ktorý označuje, či bol Dispose() vykonaný; Zavolajte GC.SuppressFinalize(this) na zrušenie ukončovacej operácie objektu; 3. Pridať chránenú virtuálnu metódu Dispose() k typu, ktorý potrebuje polymorfizmus, a odvodená trieda uvoľní svoju úlohu prepísaním tejto metódy. 4. V type, ktorý vyžaduje IDizoposovateľné rozhranie, by sme mali implementovať terminátor, aj keď ho nepotrebujeme.
19. Definovať a implementovať rozhrania nad typmi dedičnosti
1. Nesúvisiace typy môžu spoločne implementovať spoločné rozhranie a je jednoduchšie implementovať rozhranie než dedičnosť; 2. Rozhranie je relatívne stabilné, zapuzdrí súbor funkcií v rozhraní ako iné typy implementačných zmlúv, zatiaľ čo základná trieda sa môže časom rozširovať.
20. Rozlíšte medzi implementáciou rozhrania a prepísaním virtuálnych metód
1. Pri implementácii rozhrania v základnej triede musí odvodená trieda použiť new na skrytie použitia metódy základnej triedy; 2. Metóda základného rozhrania triedy môže byť deklarovaná ako virtuálna metóda a následne implementovaná v odvodenej triede.
21. Použiť zverenie na vyjadrenie spätných volaní
1. Samotný delegát neposkytuje žiadne zachytenie výnimky, takže akýkoľvek multicastový delegátový volací signál ukončí celý reťazec hovorov. 2. Zobrazením a volaním každého delegačného cieľa v reťazci delegátov môžete zabrániť tomu, aby multicast delegáti vracali iba výstup posledného delegáta.
22. Použitie udalostí na definovanie externých rozhraní
1. Mala by byť deklarovaná ako spoločná udalosť a nech kompilátor vytvára metódy pridávania a presunu pre nás. 2. Použite kontajner System.ComponentModel.EventHandlerList na uloženie každého obslužovateľa udalostí a použite ho na skrytie zložitosti všetkých udalostí, keď typ obsahuje veľké množstvo udalostí.
23. Vyhnite sa vracaniu odkazov na vnútorné triedne objekty
1. Keďže prístup k objektu typu hodnoty vytvorí kópiu objektu, atribúty definovania typu hodnoty nezmenia stav vo vnútri objektu typu; 2. Konštantné typy sa môžu vyhnúť zmene stavu objektu; 3. Definovať rozhranie tak, aby obmedzilo prístup k podmnožine a minimalizovalo poškodenie vnútorného stavu objektu. 4. Definovať obalový objekt na obmedzenie prístupu k inému objektu; 5. Keď zákaznícky kód zmení interné dátové prvky, môže byť implementovaný režim Observer, aby objekt mohol overiť alebo zodpovedať zmenám.
24. Deklaratívne programovanie je lepšie ako imperatívne programovanie
Možnosť urobiť chyby vo viacerých podobných ručne písaných algoritmoch sa dá vyhnúť a poskytuje sa jasný a čitateľný kód.
25. Implementovať typy čo najviac serializovateľné
1. Typ nepredstavuje ovládacie prvky používateľského rozhrania, okno ani formulár, a typ by mal podporovať serializáciu; 2. Pri pridávaní deserializovaného atribútu NonSerializedAttribute môže byť predvolená hodnota načítaná metódou OnDeserialization(), ktorá implementuje IDeserializationCallback; 3. Pri správe verzií môžete použiť rozhranie ISerializable na flexibilné ovládanie, poskytnúť serializačný konštruktor na inicializáciu objektov podľa dát v prúde, a tiež vyžadovať povolenie pre výnimky SerializationFormatter pri implementácii. 4. Ak potrebujete vytvoriť odvodenú triedu, musíte poskytnúť metódu háku pre odvodenú triedu.
26. Použitie rozhraní IComparable a IComparer na implementáciu vzťahov triedenia
1. Rozhranie IComparable sa používa na implementáciu najprirodzenejšieho triediaceho vzťahu pre typy, preťažuje štyri porovnávacie operátory a poskytuje preťaženú verziu metódy CompareTo() na prijímanie konkrétnych typov ako parametrov. 2. IComparer sa používa na poskytovanie triediacich vzťahov, ktoré sa líšia od IComparable, alebo na poskytovanie triediacich vzťahov, ktoré samotný typ uvádza, že nie sú implementované.
27. Vyhnite sa ICloneable rozhraniam
1. Pre typy hodnôt nie je potrebné podporovať ICloneable rozhranie, stačí použiť predvolenú operáciu priradenia; 2. Pre základné triedy, ktoré môžu potrebovať podporovať ICloneable rozhrania, by sa pre ne mal vytvoriť konštruktér chránenej replikácie a IConeable rozhrania by sa mali vyhýbať.
28. Vyhnite sa núteným konverziám operátorov
Použitie konštruktorov namiesto operátorov konverzie môže konverziu zjednodušiť, čo môže ľahko viesť k zvláštnym chybám kvôli dočasnému použitiu objektov po konverzii.
29. Použitie nového modifikátora zvážte len vtedy, keď akumulácia nových verzií spôsobuje problémy
30. Implementovať zostavy kompatibilné s CLS čo najviac 1. Na vytvorenie kompatibilnej zostavy je potrebné dodržiavať dve pravidlá: parametre a typy návratových hodnôt používané všetkými verejnými a chránenými členmi zostavy musia byť kompatibilné s CLS; Každý verejný a chránený člen, ktorý nie je kompatibilný s CLS, musí mať alternatívu kompatibilnú s CLS; 2. Kontrolu typu kompatibility s CLS môžete obísť explicitnou implementáciou rozhrania a CLSCompliantAttribute nebude kontrolovať kompatibilitu súkromných členov s CLS.
31. Implementujte čo najstručnejšiu a stručnú metódu
1. JIT kompilátor kompiluje v jednotkách metód a metódy, ktoré nie sú volané, nebudú kompilované JIT; 2. Ak je kód Case príkazu v dlhšom Switchi nahradený jednou metódou naraz, čas ušetrený JIT kompilátorom sa znásobí; 3. Krátke a stručné metódy a výber menšieho počtu lokálnych premenných môžu dosiahnuť optimalizované využitie registrov; 4. Čím menej riadiacich vetiev v metóde, tým jednoduchšie je pre JIT kompilátor vložiť premenné do registrov.
32. Realizovať malé a vysoko súdržné zostavy čo najviac
1. Vložiť všetky verejné triedy a spoločné základné triedy do niektorých assemblerov, vložiť nástrojové triedy, ktoré poskytujú funkcie pre verejné triedy, vložiť do tej istej assembler, zabaliť príslušné verejné rozhrania do vlastných assemblies a nakoniec spracovať triedy, ktoré sú po celej horizontálnej pozícii v aplikácii; 2. V zásade by sa mali vytvoriť dva typy komponentov: jedna je malá a agregovaná zostava so špecifickou funkciou a druhá je veľká a široká zostava so spoločnými funkciami.
33. Obmedziť viditeľnosť typov
1. Použitie rozhraní na sprístupnenie funkcií typov nám môže uľahčiť vytváranie interných tried bez obmedzenia ich dostupnosti mimo assembleru; 2. Čím menej verejných typov je vystavených vonkajšiemu svetu, tým viac možností máte na budúce rozšírenie a implementáciu zmien.
34. Vytvoriť veľké granulárne webové API
Tým sa minimalizuje frekvencia a záťaž transakcií medzi strojmi, čím sa na server prenášajú veľké operácie a detailné vykonávania.
35. Prepisovanie je lepšie ako procesory udalostí
1. Ak procesor udalostí vyhodí výnimku, ostatné procesory v reťazci udalostí nebudú volané, ale toto sa nestane pri prepísanej virtuálnej metóde. 2. Prepisovanie je oveľa efektívnejšie ako asociačné procesory udalostí, ktoré musia iterovať celý zoznam požiadaviek, čo zaberá viac času CPU. 3. Na udalosti je možné reagovať počas behu, s väčšou flexibilitou, a viacero odpovedí môže byť priradených k tej istej udalosti. 4. Bežné pravidlo je pracovať s odvodenou udalosťou a metóda prepisovania je lepšia.
36. Fair use. .NET runtime diagnostika
1. System.Diagnostics.Debug\Trace\EventLog poskytuje všetky nástroje potrebné na pridávanie diagnostických informácií do runtime a aplikácia môže zapisovať do systémového eventlogu, keď EventLog poskytne komponent; 2. Nakoniec nepíšte vlastnú diagnostickú knižnicu, .NET FCL už má základnú knižnicu, ktorú potrebujeme.
37. Použitie štandardných konfiguračných mechanizmov
1、. Trieda System.Windows.Application v .NET frameworku definuje vlastnosti, ktoré nám umožňujú nastaviť spoločnú konfiguračnú cestu; 2. Application.LocalAppDataPath a Application.userDataPath vygenerujú názvy ciest lokálneho adresára dát a používateľských dát; 3. Nezapisujte dáta do systémových adresárov ProgramFiles a Windows, tieto miesta vyžadujú vyššie bezpečnostné oprávnenia, neočakávajte, že používatelia budú mať oprávnenia na zápis.
38. Prispôsobiť a podporiť viazanie dát
1. Dva objekty BindingMananger a CurrencyManager realizujú prenos dát medzi kontrolou a zdrojom dát; 2. Výhody viazania dát: používanie viazania dát je oveľa jednoduchšie ako písanie vlastného kódu; Mal by sa používať aj pre rozsahy iné než textové dátové položky – aj iné zobrazovacie vlastnosti môžu byť obmedzené; Pre dátové väzby vo Windowos Forms možnosť synchronizácie viacerých kontrolných zdrojov súvisiacich s kontrolou; 3. Keď objekt nepodporuje požadované atribúty, môžete podporiť viazanie dát blokovaním aktuálneho objektu a následným pridaním požadovaného objektu.
39. Použitie. .NET validácia
1. V ASP.NET je päť ovládacích prvkov na overenie platnosti a môžete použiť CustomValidator na odvodenie novej triedy na pridanie vlastného autentifikátora. 2. Overenie Windows vyžaduje podsystém.Windows.Forms.Control.Validating na napísanie obslužovateľa udalostí.
40. Vyberte vhodné ** podľa potrieb
1. Pole má dve zjavné chyby: nedá sa dynamicky zmenšiť; Zmena veľkosti je časovo náročná; 2. ArrayList kombinuje charakteristiky jednorozmerných polí a prepojených zoznamov, Queue a Stack sú špeciálne polia založené na Array; 3. Keď je program flexibilnejší pri pridávaní a odstraňovaní položiek, môže vytvárať robustnejšie typy a pri vytváraní triedy, ktorá simuluje **, by mal implementovať indexery a IEnumerovateľné rozhrania pre ňu.
41. DataSet je lepší ako vlastná štruktúra
1. DataSety majú dve nevýhody: interakcia medzi DataSetmi používajúcimi XML serializáciu a non-.NET kódom nie je veľmi dobrá; DataSet je veľmi všestranný kontajner; 2. Silné typy DataSetov porušujú viac návrhových pravidiel a ich efektivita vývoja je oveľa vyššia ako u elegantnejších návrhov napísaných samostatne.
42. Použitie charakteristík na zjednodušenie reflexie
Navrhovaním a implementáciou tried funkcií, ktoré nútia vývojárov deklarovať dynamicky použiteľné typy, metódy a atribúty, môžete znížiť chyby pri behu aplikácie a zlepšiť spokojnosť používateľov softvéru.
43. Vyhnite sa nadmernému používaniu reflexov
1. Parametre a návratové hodnoty používané členmi Invoke sú System.Object, ktorý konvertuje typy za behu, ale možnosť problémov je pravdepodobnejšia. 2. Rozhranie nám umožňuje získať jasnejší a udržiavateľnejší systém a reflexia je veľmi silný mechanizmus neskorého viazania. .NET framework ho používa na implementáciu viazania dát pre Windows ovládacie prvky a webové kontroly.
44. Vytvorte špecifické triedy výnimiek pre aplikáciu
1. Jediným dôvodom, prečo sú potrebné rôzne triedy výnimiek, je umožniť používateľom jednoducho používať rôzne prístupy k rôznym chybám pri písaní procesorov catch; 2. Keď môžu existovať rôzne správania opravy, mali by sme vytvoriť rôzne triedy výnimiek, poskytnutím všetkých konštruktorov podporovaných základnou triedou výnimky môžeme vytvoriť plne funkčnú triedu výnimky pre aplikáciu a použiť atribút InnerException na uloženie všetkých informácií o chybách generovaných nižšími úrovňovými chybovými stavmi.
45. Uprednostniť abnormálne bezpečnostné záruky
1. Silná záruka výnimky poskytuje najlepšiu rovnováhu medzi obnovou z výnimky a zjednodušeným spracovaním výnimiek, pričom stav programu zostáva nezmenený, keď je operácia prerušená kvôli výnimke. 2. Vykonať obranné kopírovanie dát, ktoré sa majú modifikovať, upraviť obrannú kópiu týchto údajov, operácia v strede môže spôsobiť výnimku a dočasná kópia s pôvodným objektom sa vymenia; 3. Terminátory, metódy Dispose() a cieľové metódy viazané na delegátov by mali zabezpečiť, aby za žiadnych okolností nevytvárali výnimky.
46. Minimalizovať interoperabilitu
1. Interoperabilita má tri náklady: náklady na enumeráciu dát medzi spravovanými a nespravovanými haldami, náklady na prepínanie medzi spravovaným a nespravovaným kódom a vývojovú prácu vývojárov pracujúcich s hybridnými prostrediami; 2. Použitie typu blittable v interoperácii umožňuje efektívne replikovať medzi spravovaným a nespravovaným prostredím bez ovplyvnenia vnútornou štruktúrou objektu. 3. Použiť funkciu In/Out na zabezpečenie najvhodnejších zbytočných viacerých replikácií a zlepšiť výkon deklarovaním spôsobu enumerácie dát. 4. Použiť COM Interop na implementáciu interoperability s COM komponentmi najjednoduchším spôsobom, použiť P/Invoke na volanie Win32 API alebo použiť prepínač /CLR v kompilátore C++ na zmiešanie spravovaného a nespravovaného kódu;
47. Uprednostniť bezpečnostné kódy
1. Vyhýbajte sa prístupu k nespravovanej pamäti čo najviac, izolované úložisko nemôže zabrániť prístupu spravovaného kódu a dôveryhodných používateľov. 2. Keď assemblery bežia na webe, zvážte použitie izolovaného úložiska, a ak niektoré algoritmy vyžadujú vyššie bezpečnostné oprávnenia, tieto kódy by mali byť izolované v samostatnej zostave.
48. Zvládnuť relevantné nástroje a zdroje
1. Použiť NUnit na zavedenie automatických jednotkových testov (integrovaných vo VS2010); 2. Nástroj FXCop získa IL kód v zostave, analyzuje ho podľa heterogénnych kódovacích pravidiel a najlepších postupov a nakoniec nahlási porušenie. 3. ILDasm je nástroj na rozoberanie IL, ktorý nám môže pomôcť získať prehľad o detailoch; 4. Shared Source CLI je implementačný zdrojový kód, ktorý obsahuje jadro .NET frameworku a kompilátor C#. |