Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 20516|Odpověď: 0

[Tipy] Čtyřicet sedm způsobů, jak optimalizovat program v C#

[Kopírovat odkaz]
Zveřejněno 15.03.2018 10:41:59 | | |

1. Nahradit přístupná pole atributy

1、. .NET datové vazby podporují pouze vazbu dat a výhody vazby dat můžete získat použitím atributů.
2. Při přístupu k vlastnosti můžete použít zámek k přidání podpory vícevláknového zpracování.

2. readonly (runtime konstanta) a const (kompilační konstanta)

1. const lze použít pouze pro primitivní typy, enumy a řetězce, zatímco readonly může být jakýkoli typ;
2. Const bude při kompilaci nahrazen konkrétní konstantou, takže pokud jsou v referenci použity hodnoty const i readonly only, změna na readonly změní původní záměr návrhu, tedy nutnost znovu zkompilovat změněnou sestavu pro referenci na novou konstantní hodnotu.
3. Const je efektivnější než pouze pro čtení, ale ztrácí flexibilitu aplikace.

3. IS a AS

1. Oba jsou převody typů za běhu, protože operátory lze použít pouze v referenčních typech, zatímco is může používat hodnoty a referenční typy;
2. Obvyklou praxí je použít IS k určení typu a poté zvolit použití jako nebo silného operátoru převodu typů (převod definovaný operátorem) selektivně.

4. Podmíněný atribut místo #if #endif条件编译

1. Podmíněný atribut se používá pouze na úrovni metody a další položky jako typy, atributy atd. jsou neplatné. A #if #endif则不受此限制;
2. Podmíněný atribut může přidat více operací OR (OR) pro podmínky kompilace a #if #endif则可以添加与(AND) [zde lze zcela definovat jako další samostatný symbol];
3. Definici ConditioanlAttribute lze umístit do samostatné metody, aby byl program flexibilnější.

5. Poskytnout metodu ToString()

1. Může uživatelům poskytovat podrobnější informace přívětivějším způsobem;
2. Použijte metodu IFormatter.ToString() pro flexibilnější přizpůsobení, a pokud přidáte rozhraní IFormatProvider a ICustomFormatter, bude dávat větší smysl přizpůsobit výstup zprávy.

6. Rozdíl mezi hodnotou a typem reference

1. Hodnoty nepodporují polymorfismus, který je vhodný pro ukládání dat provozovaných aplikacemi, zatímco reference podporují polymorfismus, který je vhodný pro definování chování aplikací.
2. Pro pole definovaná jako hodnoty lze výrazně zlepšit výkon programu;
3. Typ hodnoty má menší fragmentaci haldy paměti, nesmysl paměti a čas nepřímého přístupu a jeho návrat v metodě je realizován formou replikace, aby se zabránilo vystavení vnitřní struktury vnějšímu světu.
4. Hodnoty typů se používají v následujících scénářích: Odpovědnosti typů se používají především pro ukládání dat; Veřejná rozhraní jsou zcela definována některými atributy přístupu datových členů; Podtřídy nikdy neexistují; Nikdy neexistuje polymorfní chování.

7. Typy hodnot by měly být implementovány co nejvíce konstantními a atomickými typy

1. Usnadnit psaní a údržbu našeho kódu;
2. Tři strategie inicializace konstant: při konstrukci; rostlinná metoda; Vytvořte proměnnou pomocnou třídu (např. StringBuilder).

8. Zajistit, že 0 je hodna platného statusu

1. Výchozí stav typu hodnoty by měl být 0;
2. 0 enum typu by nemělo být neplatné; V atributu Flags je zajištěno, že hodnota 0 je platný stav;
3. Když je řetězec prázdný, lze řetězec vrátit. prázdný řetězec místo prázdný.

9. Vztahy vícenásobného zastupování se stejným soudem

1. ReferenceEquals() určuje, že odkazy jsou si rovné, a musí to platit, pokud obě odkazují na stejný objekt.
2. Statická metoda Equals() se používá nejprve k referenčnímu úsudku a poté k posouzení typu hodnoty;
3. Pro posouzení typu reference můžete použít metodu přepisování Equals() při použití sémantiky hodnot.
4. Při přepsání metody Equals() by měla být přepsána také metoda GetHashCode() a současně by měla být poskytnuta operace operátor==().

10. Pochopte nedostatky metody GetHashCode()

1. GetHashCode() se aplikuje pouze na hashovací hodnoty hashovacích ** definovaných klíčů, jako je HashTable nebo Dictionary;
2. GetHashCode() by měl dodržovat odpovídající tři pravidla: dva stejné objekty by měly vracet stejný hash kód; by měl být invariantní instance; Hašovací funkce by měla generovat náhodné rozdělení napříč všemi celými čísly.

11. Upřednostnit použití foreach příkazů smyček

1. foreach může eliminovat kontrolu kompilátoru nad hranicí pole ve forové smyčce;
2. Kruhová proměnná foreach je pouze pro čtení a existuje explicitní transformace, která vyhodí výjimku, když je typ objektu ** nesprávný;
3. Potřeba ** pro použití foreach je: mít veřejnou metodu GetEnumberator(); Rozhraní IEnumberable je explicitně implementováno. Je implementováno rozhraní IEnumeratoru;
4. foreach může přinést výhody správy zdrojů, protože pokud kompilátor dokáže určit IDisposable rozhraní, může použít optimalizované try... nakonec blok;

12. Inicializace výchozího pole je lepší než příkaz přiřazení

1. Životní hodnota pole inicializuje typ hodnoty na 0 a referenční typ na null ve výchozím nastavení.
2. Opakovaná inicializace stejného objektu sníží efektivitu vykonávání kódu.
3. Vložení inicializace pole do konstruktoru je vhodné pro zpracování výjimek.

13. Použít statický konstruktor k inicializaci statických členů

1. Statický konstruktor bude vykonán před přístupem k jakékoli metodě, proměnné nebo atributu třídy;
2. Statická pole také běží před statickým konstruktorem a statický konstruktor je vhodný pro zpracování výjimek.

14. Použijte konstruktorový řetězec (v. NET 4.0 už tento problém řeší volitelnými parametry)

1. Použít toto k předání inicializační práce jinému konstruktoru a použít základnu k volání konstruktora základní třídy;
2. Sekvence operací typů instancí je: nastavte všechna statická pole na 0; Provádění inicializátorů statického pole; statický konstruktor, který vykonává základní třídu; Statické konstruktory, které vykonávají aktuální typ;
Nastavte všechna pole instance na 0; Spustit inicializátory pole instance; Spustit příslušný konstruktor instance základní třídy; Spusť konstruktor instance aktuálního typu.

15. Používání příkazů using a try/finally k vyčištění zdrojů

V metodě Dispose() rozhraní IDisposable lze GC.SuppressFinalize() použít k upozornění garbage collectoru, že poslední operace již není prováděna.

16. Minimalizujte paměťový odpad

1. Přidělování a zničení objektů na haldě vyžaduje více procesorového času;
2. Techniky pro snížení počtu přiřazených objektů: často používané lokální proměnné jsou povýšeny do polí; Poskytuje třídu, která ukládá běžné instance objektů Singleton, které vyjadřují specifické typy.
3. Použijte StringBuilder pro provádění složitých řetězcových operací.

17. Minimalizovat balení a vybalování

1. Věnovat pozornost implicitnímu převodu typu na System.Object, a hodnota typu by neměla být nahrazena typem System.Object;
2. Použití rozhraní místo typů může vyhnout se boxingu, tedy implementaci hodnotových typů z rozhraní a následnému volání členů přes rozhraní.

18. Implementovat standardní režim Likvidace

1. Pro použití nepaměťových zdrojů musí mít finalizer, garbage collector přidá implementované objekty finalizéru do terminační fronty po dokončení paměťových objektů, které je neukončily, a poté garbage collector začne nové vlákno, které spustí finalizery na těchto objektech. Tím se může předejít problému úniku paměti způsobeného neuvolňováním nespravovaných paměťových zdrojů.
2. Použití metody IDisposable.Dispose() vyžaduje čtyři aspekty práce: uvolnění všech nespravovaných zdrojů; Uvolněte všechny spravované zdroje; Nastavte stavový marker, který označí, zda byl Dispose() vykonán; Zavolejte GC.SuppressFinalize(this) pro zrušení operace ukončení objektu;
3. Přidejte chráněnou virtuální metodu Dispose() k typu, který potřebuje polymorfismus, a odvozená třída uvolní svou úlohu přepisem této metody.
4. V typu, který vyžaduje IDizoposibilní rozhraní, bychom měli implementovat terminátor, i když ho nepotřebujeme.

19. Definujte a implementujte rozhraní nad typy dědičnosti

1. Nesouvisející typy mohou společně implementovat společné rozhraní a je snazší implementovat rozhraní než dědičnost;
2. Rozhraní je relativně stabilní, zapouzdřuje sadu funkcí v rozhraní jako jiné typy implementačních kontraktů, zatímco základní třída může být v čase rozšiřována.

20. Rozlište mezi implementací rozhraní a přepisováním virtuálních metod

1. Při implementaci rozhraní v základní třídě musí odvozená třída použít new, aby skryla použití metody základní třídy;
2. Metoda rozhraní základní třídy může být deklarována jako virtuální metoda a následně implementována v odvozené třídě.

21. Použít svěření k vyjádření callbacků

1. Samotný delegát neposkytuje žádné zachycení výjimek, takže jakýkoli multicast volací příkaz ukončí celý řetězec hovorů.
2. Zobrazením a vyvoláním každého delegačního cíle v delegátním řetězci můžete zabránit tomu, aby multicastové delegáty vracely pouze výstup posledního delegáta.

22. Použití událostí k definování externích rozhraní

1. Mělo by být deklarováno jako společná událost a nechat kompilátor vytvářet metody přidávaní a přesouvání pro nás.
2. Použijte kontejner System.ComponentModel.EventHandlerList pro uložení každého obslužného nástroje událostí a použijte ho ke skrytí složitosti všech událostí, pokud typ obsahuje velké množství událostí.

23. Vyhněte se vracení odkazů na interní objekty třídy

1. Protože přístup k objektu typu hodnoty vytvoří kopii objektu, atributy definující typ hodnoty vůbec nezmění stav uvnitř objektu typu;
2. Typy konstant se mohou vyhnout změně stavu objektu;
3. Definujte rozhraní tak, aby omezilo přístup k podmnožině a minimalizovalo poškození vnitřního stavu objektu.
4. Definovat obalový objekt pro omezení přístupu k jinému objektu;
5. Když zákaznický kód změní interní datové prvky, lze implementovat režim Observer, aby objekt mohl ověřit nebo odpovídat změnám.

24. Deklarativní programování je lepší než imperativní programování

Lze se vyhnout možnosti chyb v několika podobných ručně psaných algoritmech a poskytuje se jasný a čitelný kód.

25. Implementovat typy co nejvíce serializovatelné

1. Typ nepředstavuje ovládací prvky uživatelského rozhraní, okno ani formulář, a typ by měl podporovat serializaci;
2. Při přidání deserializovaného atributu NonSerializedAttribute lze výchozí hodnotu načíst metodou OnDeserialization(), která implementuje IDeserializationCallback;
3. Při řízení verzí můžete použít ISerializable rozhraní pro flexibilní řízení a poskytnout serializační konstruktor pro inicializaci objektů podle dat v proudu, a také vyžadovat povolení pro výjimky SerializationFormatter při implementaci.
4. Pokud potřebujete vytvořit odvozenou třídu, musíte poskytnout hookovou metodu pro odvozenou třídu.

26. Použití rozhraní IComparable a IComparer k implementaci vztahů třídění

1. IComparable rozhraní se používá k implementaci nejpřirozenějšího seřazovacího vztahu pro typy, což přetěžuje čtyři srovnávací operátory a poskytuje přetíženou verzi metody CompareTo() pro přijímání konkrétních typů jako parametrů.
2. IComparer se používá k poskytování seřazovacích vztahů, které se liší od IComparable, nebo k poskytnutí seřazovacích vztahů, které typ sám uvádí, že nejsou implementovány.

27. Vyhněte se ICloneable rozhraním

1. Pro typy hodnot není potřeba podporovat ICloneable rozhraní, stačí použít výchozí operaci přiřazení;
2. Pro základní třídy, které mohou potřebovat ICloneable rozhraní, by pro ně měl být vytvořen konstruktor chráněné replikace a IConeable rozhraní by se měla vyhnout.

28. Vyhnout se nuceným převodům operátorů

Použití konstruktorů místo konverzních operátorů může převod zjednodušit, což může snadno vést k podivným chybám kvůli dočasným objektům použitým po konverzi.

29. Zvažte použití nového modifikátoru pouze tehdy, když hromadění nových verzí způsobuje problémy

30. Implementovat co nejvíce sestavení kompatibilní s CLS
1. Pro vytvoření kompatibilního assembleru je třeba dodržovat dvě pravidla: parametry a typy return value používané všemi veřejnými a chráněnými členy assembleru musí být kompatibilní s CLS; Každý veřejný a chráněný člen, který není kompatibilní s CLS, musí mít CLS-kompatibilní alternativu;
2. Kontrolu typu kompatibility s CLS lze obejít explicitní implementací rozhraní a CLSCompliantAttribute nebude kontrolovat kompatibilitu soukromých členů s CLS.

31. Implementovat co nejstručnější a nejstručnější metodu

1. JIT kompilátor kompiluje v jednotkách metod a metody, které nejsou volány, nebudou JIT kompilovat;
2. Pokud je kód Case příkazu v delším Switchi nahrazen jednou metodou najednou, čas ušetřený JIT kompilátorem se vynásobí;
3. Krátké a stručné metody a výběr menšího počtu lokálních proměnných mohou dosáhnout optimalizovaného využití registrů;
4. Čím méně řídicích větví v metodě, tím snazší je pro JIT kompilátor vložit proměnné do registrů.

32. Realizovat malé velikosti a vysoce soudržné sestavy co nejvíce

1. Umístit všechny veřejné třídy a společné základní třídy do některých assemblů, umístit nástrojové třídy, které poskytují funkce pro veřejné třídy, vložit do stejného assembleru, zabalit příslušná veřejná rozhraní do vlastních assemblerů a nakonec zpracovat třídy, které jsou v aplikaci po celé horizontální pozici;
2. V zásadě by měly být vytvořeny dva typy komponent: jedna je malá a agregovaná sestava s konkrétní funkcí a druhá je velká a široká sestava se společnými funkcemi.

33. Omezit viditelnost typů

1. Použití rozhraní k zobrazení funkcí typů nám může usnadnit vytváření interních tříd, aniž bychom omezili jejich dostupnost mimo assembler;
2. Čím méně veřejných typů je vystaveno vnějšímu světu, tím více možností máte pro budoucí rozšíření a změny implementací.

34. Vytvořit rozsáhlé webové API

To minimalizuje frekvenci a zátěž transakcí mezi stroji, což umožňuje velké operace a detailní provádění na server.

35. Přepisování je lepší než event processory

1. Pokud event processor vyhodí výjimku, ostatní procesory v event chain nebudou vyvolány, ale to se nestane u přepsané virtuální metody.
2. Přepisování je mnohem efektivnější než asociativní procesory událostí, které musí iterovat celý seznam požadavků, což zabírá více času CPU.
3. Na události lze reagovat za běhu s větší flexibilitou a více odpovědí může být přiřazeno ke stejné události.
4. Běžné pravidlo je pracovat s odvozenou událostí a metoda přepisu je lepší.

36. Fair use. .NET runtime diagnostika

1. System.Diagnostics.Debug\Trace\EventLog poskytuje všechny nástroje potřebné programu, aby mohl přidat diagnostické informace do runtime, a aplikace může zapisovat do systémového event logu, když EventLog poskytne komponentu;
2. Nakonec si nepište vlastní diagnostickou knihovnu, .NET FCL už má základní knihovnu, kterou potřebujeme.

37. Použijte standardní konfigurační mechanismy

1、. Třída System.Windows.Application v .NET frameworku definuje vlastnosti, které nám umožňují nastavit společnou konfigurační cestu;
2. Application.LocalAppDataPath a Application.userDataPath vygenerují názvy cest místního datového adresáře a uživatelských dat;
3. Neupisujte data do systémových adresářů ProgramFiles a Windows, tato místa vyžadují vyšší bezpečnostní oprávnění, neočekávejte uživatele oprávnění k zápisu.

38. Přizpůsobení a podpora datového vazby

1. Dva objekty BindingMananger a CurrencyManager realizují přenos dat mezi kontrolou a zdrojem dat;
2. Výhody vazby dat: použití datového vazby je mnohem jednodušší než psaní vlastního kódu; Měl by být použit i pro rozsahy jiné než textové datové položky – jiné vlastnosti zobrazení lze také omezit; U datových vazeb ve Windowos Forms možnost zvládnout synchronizaci více kontrolních prvků datových zdrojů souvisejících s kontrolou;
3. Pokud objekt nepodporuje požadované atributy, můžete podpořit datové vazby blokováním aktuálního objektu a následným přidáním požadovaného objektu.

39. Použití. .NET validace

1. V ASP.NET je pět kontrolních prvků pro ověření platnosti a můžete použít CustomValidator k odvození nové třídy pro přidání vlastního autentizátoru.
2. Validace Windows vyžaduje podsystém.Windows.Forms.Control.Validating pro napsání obslužného nástroje událostí.

40. Vyberte vhodné ** podle potřeb

1. Pole má dvě zjevné vady: nelze jej dynamicky měnit; Změna velikosti je časově náročná;
2. ArrayList kombinuje charakteristiky jednorozměrných polí a propojených seznamů, Queue a Stack jsou speciální pole založená na poli;
3. Když je program flexibilnější pro přidávání a mazání položek, může vytvářet robustnější typy a při vytváření třídy, která simuluje **, by měl implementovat indexery a IEnumberable rozhraní pro ni.

41. DataSet je lepší než vlastní struktura

1. DataSety mají dvě nevýhody: interakce mezi DataSety pomocí XML serializace a non-.NET kódem není příliš dobrá; DataSet je velmi univerzální kontejner;
2. Silné typy datových sad porušují více návrhových pravidel a jejich efektivita vývoje je mnohem vyšší než u elegantnějších návrhů napsaných samostatně.

42. Použití charakteristik ke zjednodušení reflexe

Navrhováním a implementací tříd funkcí, které nutí vývojáře deklarovat dynamicky použitelné typy, metody a atributy, můžete snížit chyby při běhu aplikace a zlepšit spokojenost uživatelů softwaru.

43. Vyhněte se nadměrnému používání reflexů

1. Parametry a návratové hodnoty používané členy Invoke jsou System.Object, který převádí typy za běhu, ale možnost problémů je pravděpodobnější.
2. Rozhraní nám umožňuje získat jasnější a lépe udržovatelný systém a reflexe je velmi silný mechanismus pozdního vazby. .NET framework jej využívá k implementaci datového vazby pro Windows a webové kontroly.

44. Vytvořte specifické třídy výjimek pro aplikaci

1. Jediným důvodem, proč jsou potřeba různé třídy výjimek, je umožnit uživatelům snadno zvolit různé přístupy k různým chybám při zápisu procesorů catch;
2. Pokud mohou existovat různé opravné chování, měli bychom vytvořit různé třídy výjimek, a poskytnutím všech konstruktorů podporovaných základní třídou výjimky můžeme vytvořit plně funkční třídu výjimek pro aplikaci a použít atribut InnerException k uložení všech chybových informací generovaných nižšími chybovými stavy.

45. Upřednostnit neobvyklé bezpečnostní záruky

1. Silná záruka výjimek poskytuje nejlepší rovnováhu mezi obnovou z výjimek a zjednodušeným zpracováním výjimek a stav programu zůstává nezměněn, když je operace přerušena kvůli této výjimce.
2. Provést obranné kopírování dat, která mají být upravena, upravit obrannou kopii těchto dat, operace uprostřed může způsobit výjimku a dočasná kopie s původním objektem budou vyměněny;
3. Terminátory, metody Dispose() a cílové metody vázané na delegáty by měly zajistit, že za žádných okolností nevyvolávají výjimky.

46. Minimalizovat interoperabilitu

1. Existují tři náklady na interoperabilitu: náklady na výčet dat mezi spravovanými a nespravovanými haldami, náklady na přepínání mezi řízeným a nespravovaným kódem a vývojová práce vývojářů pracujících s hybridními prostředími;
2. Použití typu blittable v interoperaci může efektivně replikovat mezi spravovaným a nespravovaným prostředím, aniž by bylo ovlivněno vnitřní strukturou objektu.
3. Použijte funkci In/Out k zajištění nejvhodnějších zbytečných vícenásobných replikací a zlepší výkon tím, že deklarujete, jak jsou data vyčíslována.
4. Použít COM Interop pro co nejjednodušší implementaci interoperability s COM komponentami, použít P/Invoke pro volání Win32 API nebo použít přepínač /CLR v kompilátoru C++ pro kombinaci spravovaného a nespravovaného kódu;

47. Upřednostnit bezpečnostní kódy

1. Vyhněte se co nejvíce přístupu k nespravované paměti a izolované úložiště nemůže zabránit přístupu spravovaného kódu a důvěryhodných uživatelů.
2. Když assemblery běží na webu, zvažte použití izolovaného úložiště a pokud některé algoritmy vyžadují vyšší bezpečnostní oprávnění, měly by být tyto kódy izolovány v samostatném assembleru.

48. Ovládnout relevantní nástroje a zdroje

1. Použití NUnit k vytvoření automatických jednotkových testů (integrovaných ve VS2010);
2. Nástroj FXCop získá IL kód v assembleru, analyzuje jej podle heterogenních kódovacích pravidel a osvědčených postupů a nakonec nahlásí porušení.
3. ILDasm je nástroj pro rozkládání IL, který nám může pomoci získat vhled do detailů;
4. Sdílený zdrojový CLI je implementační zdrojový kód, který obsahuje jádro .NET frameworku a kompilátor C#.




Předchozí:Service Fabric – koncept stavové služby
Další:.net/c# SynchronizationContext pro podrobnosti
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com