tag:blogger.com,1999:blog-29937626796770617632024-03-23T11:14:02.437+01:00Martin's cornerStřípky ze života ajťákamstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.comBlogger125125tag:blogger.com,1999:blog-2993762679677061763.post-35511018986362153732017-12-09T12:39:00.000+01:002017-12-09T12:39:36.456+01:00Jak se vyhnout chybě CA1303: Do not pass literals as localized parameters <div style="text-align: justify;">
<div style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizMx0vdB5qMcQ_3lWiTGXqS-Rl8qast_oHoQnP4t57_b2qYfp_ZSzBmNNTcq_dhv9-lOjv9IP6g1Cw1HJvBEvy1RplhHPrhug6qhijWkiZnb8bBPKf74jPGhdaeJjZk3Dt4tzRlCBJixk/s1600/searchCode.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="240" data-original-width="210" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizMx0vdB5qMcQ_3lWiTGXqS-Rl8qast_oHoQnP4t57_b2qYfp_ZSzBmNNTcq_dhv9-lOjv9IP6g1Cw1HJvBEvy1RplhHPrhug6qhijWkiZnb8bBPKf74jPGhdaeJjZk3Dt4tzRlCBJixk/s200/searchCode.jpg" width="175" /></a></div>
Pokud je zapnuta analýza kódu a nastavena většina pravidel, stane se při zavedení nové metody, která používá jako parameter string a jejím volání, že kompilace kódu skončí chybou.<br />
<br />
Ono je to technicky vzato varování, ale lze si v projeku nastavit, že tato varování budou považovány za chybu.<br />
<br />
<a name='more'></a></div>
<br />
Mějme podobnou metodu:</div>
<br />
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">object</span> ThrowIfNull<<span style="color: #2b91af;">TException</span>>(<span style="color: blue;">this</span> <span style="color: blue;">object</span> value, <span style="color: blue;">string</span> message) <span style="color: blue;">where</span> <span style="color: #2b91af;">TException</span> : <span style="color: #2b91af;">Exception</span>
{
<span style="color: blue;">if</span> (value == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> (<span style="color: #2b91af;">TException</span>)<span style="color: #2b91af;">Activator</span>.CreateInstance(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">TException</span>), message);
}
<span style="color: blue;">return</span> value;
}</pre>
<br />
A pokud ji voláme:<br />
<br />
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;">course.ThrowIfNull<<span style="color: #2b91af;">ResourceNotFoundException</span>>(<span style="color: #a31515;">"The requested course is not found in the Course database."</span>);</pre>
<br />
Dostaneme následující chybu při kompilaci:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">CA1303<span style="white-space: pre;"> </span>Method 'xxx' passes a literal string as parameter 'message' of a call to 'GuardHelperExtensions.ThrowIfNull<ResourceNotFoundException>(this object, string)'. Retrieve the following string(s) from a resource table instead: "The requested course is not found in the Course database.".<span style="white-space: pre;"> </span></span><br />
<div>
<br /></div>
Hlášku dostanete, když se pokusíme přes parametr přímo předat řetězec a něco z tohoto je splněno:<br />
<ul>
<li><b>LocalizableAttribute</b> parameteru je nastaven na <b>true </b></li>
<li>Parametr má v názvu slova jako <b>Text</b>, <b>Message </b>nebo <b>Caption </b></li>
</ul>
<br />
<div style="text-align: justify;">
Na výběr je pak buď potlačit toto hlášení přes <b>SuppressMessage</b> atribut na dotčeném místě a nebo, pokud volaná metoda je upravitelná a jste si jisti, že žádnou lokalizaci vlastně nechcete, použitím již zmíněného <b>LocalizableAttributu</b>:
<br />
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">object</span> ThrowIfNull<<span style="color: #2b91af;">TException</span>>(<span style="color: blue;">this</span> <span style="color: blue;">object</span> value, [<span style="color: #2b91af;">Localizable</span>(<span style="color: blue;">false</span>)] <span style="color: blue;">string</span> message) <span style="color: blue;">where</span> <span style="color: #2b91af;">TException</span> : <span style="color: #2b91af;">Exception</span>
{
<span style="color: blue;">if</span> (value == <span style="color: blue;">null</span>)
{
<span style="color: blue;">throw</span> (<span style="color: #2b91af;">TException</span>)<span style="color: #2b91af;">Activator</span>.CreateInstance(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">TException</span>), message);
}
<span style="color: blue;">return</span> value;
}</pre>
A je to, při všech voláních této metody můžeme používat přímo řetězec a to bez následného chybového hlášení.</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com14tag:blogger.com,1999:blog-2993762679677061763.post-48338339603467820962017-08-07T08:42:00.000+02:002017-08-07T08:42:08.794+02:00Vývoj na VM v Azure - má to smysl a nebo ne?<div style="text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj06tNMK074FVPCq7PLsL78tZAalgxKx_OcDgXTKSgTMQH8pajNW_EHNFFSWKrLBQ_JzMuXRePH-zs7nHXUlHRAAVVVhuVYcdyeViNFdSSFKmbl2g1HGvCZjAau0JP_mci2UyrffJS23Ng/s1600/Azure-Virtual-Machine-2_COLOR.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="512" data-original-width="512" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj06tNMK074FVPCq7PLsL78tZAalgxKx_OcDgXTKSgTMQH8pajNW_EHNFFSWKrLBQ_JzMuXRePH-zs7nHXUlHRAAVVVhuVYcdyeViNFdSSFKmbl2g1HGvCZjAau0JP_mci2UyrffJS23Ng/s200/Azure-Virtual-Machine-2_COLOR.png" width="200" /></a>Při hledání možností, jak usnadnit práci novým kolegům na našem projektu byla jednou ze zvažovaných možností i použití virtuálního počítače v Azure. Nápad byl asi takový, že si uděláme předlohu, tedy ideální pracovní stroj, kde již budou nainstalovány všechny používané aplikace. Tedy mimo samozřejmého Visual Studia i všechny další nástroje pro práci s kódem, všechny potřebné SDK, testovací nástroje a další.<br />
Nováček by si tak jen na pár kliků na Azure portálu vytvořil svoji instanci, nastavil potřebné přihlašovací údaje a mohl tak prakticky ihned začít pracovat. </div>
<br />
<a name='more'></a><br />
<span style="text-align: justify;">Dnes dostane jen "holé" pracoviště, tedy laptop s nainstalovaným operačním systéme (v našem případě s Windows 10) a následně si vše musí nainstalovat a nastavit sám. Děje se tak částečně postupně, i tak ale odhadujeme, že pro přípravu a instalací všeho potřebného, je potřeba více jak tří dnů. Oproti tomu použití předpřipraveného obrazu a VM by tuto dobu mohlo zkrátit na půl dne. Díky tomu, že veškerá práce probíhá na VM v Azure, není nutné mít nějaký extra výkonný hardware lokálně a dojde tak i k určité úspoře nákladů. </span><br />
<span style="text-align: justify;">Na druhou stanu je ale nutné připravit a udržovat obraz našeho vývojářského prostředí na Azure a implementovat následně i všechny přicházející aktualizace. Také na připojení k Internetu a na místní síť by byli kladeny jiné nároky.</span><br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Následné aktualizace jsou pak časově zhruba stejně shodné bez ohledu jestli se provádí na lokále a nebo na vzdáleném virtuální počítači.</div>
<br />
<div style="text-align: justify;">
Práci s VM si občas zkouším - a je fakt, že se to o hodně zlepšilo, ale zpoždění je občas patrné a člověk má občas pocit, že to "není ono" - ale katastrofální to rozhodně není. Problémy začnou se sítí - na mé domácí síti stačí, aby někdo začal něco uploadovat a jakžtakž pocit, že to jde, je rázem pryč. Kvalitní konektivita je tedy nutnou podmínkou.<br />
<br />
<h3>
Kolik ušetříme?</h3>
</div>
<div style="text-align: justify;">
Ale dává to vůbec smysl po finanční stránce? Zkoušel jsem si to propočítat, všechny ceny jsou v amerických dolarech a časové údaje ve dnech, vše počítáno na dobu tří let:<br />
<br />
Provoz VM něco stojí - naprostým minimem je asi konfigurace A3 (4 jádra. 7GB RAM a 120GB disku), která při důsledném vypínání po skončení pracovní doby stojí kolem 40 dolarů měsíčně. Ale to je minimum, kterého se nepodaří v praxi dosáhnout. Hodina práce s instancí o velikosti A4 (což je 8 jader, 14 GB RAM a 240GB diskového prostoru) stojí 60 centů. Pokud bude tato instance běžet 10 hodin denně, 21 dnů v měsíci, bude nás provoz za 3 roky stát kolem 4500 USD.<br />
<br />
Pokud to vše nějak shrnu, tak pro provoz VM jsou rozhodující tyto náklady - vše pro dobu tří let:<br />
<br />
<ul>
<li>DevOps stráví celkem asi 15 dnů přípravou a následnou aktualizací obrazů</li>
<li>Vývojář pak prvotním nastavením stráví půl dne, během tří let každí tři měsíce stráví čtrtinu dne aktualizacemi OS, VS a dalších nástrojů - celkem tedy asi 3dny.</li>
<li>Laptop bude stát 1000 USD, provozní náklady VM budou 4500 USD, celkem tedy 5500 USD</li>
</ul>
<br />
Při lokálním vývoji jsou náklady tyto:<br />
<br />
<ul>
<li>Vývojář stráví prvotním nastavením tři a půl dne, podobně jako u BM pak každé tři měsíce čtvrt dne obětuje aktualizacím, celkově tedy touto praí stráví 6 dnů</li>
<li>Laptop bude stát 2500 USD - bude mít více lepší CPU, více RAM, rychlý SSD disk.</li>
</ul>
<br />
Dáno do tabulky, lze si snadno vypočítat, kolik bude ušetřený den stát v závislosti na počtu vývojářů:<br />
<style type="text/css"><!--td {border: 1px solid #ccc;}br {mso-data-placement:same-cell;}--></style><br />
<table border="1" cellpadding="0" cellspacing="0" dir="ltr" style="border-collapse: collapse; border: none; font-family: arial,sans,sans-serif; font-size: 10pt; table-layout: fixed;" xmlns="http://www.w3.org/1999/xhtml"><colgroup><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col></colgroup><tbody>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"developers"}" style="border-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;"># developers</td><td data-sheets-value="{"1":3,"3":5}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">5</td><td data-sheets-value="{"1":3,"3":10}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">10</td><td data-sheets-value="{"1":3,"3":15}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">15</td><td data-sheets-value="{"1":3,"3":30}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">30</td><td data-sheets-value="{"1":3,"3":60}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">60</td><td data-sheets-value="{"1":3,"3":90}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">90</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"VM days"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">VM days</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":30}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">30</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":45}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">45</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":60}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">60</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":105}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">105</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":195}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">195</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":285}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">285</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"VM price"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">VM price USD</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":27500}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">27500</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":55000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">55000</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":82500}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">82500</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":165000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">165000</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":330000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">330000</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":495000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">495000</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"LM days"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">LM days</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":30}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">30</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":60}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">60</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":90}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">90</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":180}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">180</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":360}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">360</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":540}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">540</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"LM price"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">LM price USD</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":12500}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">12500</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":25000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">25000</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":37500}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">37500</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":75000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">75000</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":150000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">150000</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":225000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">225000</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"Price for a day"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">Price for a day saved in USD</td><td data-sheets-formula="= ROUND ((R[-3]C[0]-R[-1]C[0])/ IF((R[-2]C[0]-R[-4]C[0])>0,R[-2]C[0]-R[-4]C[0],1))" data-sheets-value="{"1":3,"3":15000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">15000</td><td data-sheets-formula="= ROUND ((R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0]))" data-sheets-value="{"1":3,"3":2000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">2000</td><td data-sheets-formula="= (R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0])" data-sheets-value="{"1":3,"3":1500}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">1500</td><td data-sheets-formula="= (R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0])" data-sheets-value="{"1":3,"3":1200}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">1200</td><td data-sheets-formula="= ROUND ((R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0]))" data-sheets-value="{"1":3,"3":1091}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">1091</td><td data-sheets-formula="= ROUND ((R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0]))" data-sheets-value="{"1":3,"3":1059}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">1059</td></tr>
</tbody></table>
</div>
<div style="text-align: justify;">
<br />
Z tabulky tedy žádná finanční výhoda při používání VM neplyne - v malém týmu bude den ušetřené práce stát kolem 1500 USD, tedy vedlo by to spíše k prodělku. Ani u velkého týmu není úspora tisícovky dolarů něco, za co by nás finančníci moc pochválili - tedy asi ve většině českých firem.<br />
<br />
<h3>
Co s tím?</h3>
Aby to mělo smysl, je nutné:<br />
<ul>
<li>co nejvíce standardizovat vývojové prostředí s tím, že vývojář nesmí provádět žádné velké změny a IT oddělení musí mít co největší kontrolu - tak, aby ideálně odpadly i ty dny nutné na aktualizace vývojářem a celkové doba, kterou stráví "neproduktivně" se omezila jen na prvotní nastavení. </li>
<li>vyjednat slevy na provoz VM, popřípadě zvolit jinou velikost VM a přísněji dbát na dodržování doby běhu instance v Azure. </li>
<li>dělat práci s vyšší přidanou hodnotou, tedy jinými slovy pracovat produktivněji</li>
</ul>
Snížení ceny provozu VM z původních 4500 USD na 2000 USD během tří let a zkrácení doby nastavení na půl dne se projeví takto:<br />
<style type="text/css"><!--td {border: 1px solid #ccc;}br {mso-data-placement:same-cell;}--></style><br />
<table border="1" cellpadding="0" cellspacing="0" dir="ltr" style="border-collapse: collapse; border: none; font-family: arial,sans,sans-serif; font-size: 10pt; table-layout: fixed;" xmlns="http://www.w3.org/1999/xhtml"><colgroup><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col></colgroup><tbody>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"developers"}" style="border-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;"># developers</td><td data-sheets-value="{"1":3,"3":5}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">5</td><td data-sheets-value="{"1":3,"3":10}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">10</td><td data-sheets-value="{"1":3,"3":15}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">15</td><td data-sheets-value="{"1":3,"3":30}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">30</td><td data-sheets-value="{"1":3,"3":60}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">60</td><td data-sheets-value="{"1":3,"3":90}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">90</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"VM days"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">VM days</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":17.5}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">17.5</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":20}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">20</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":22.5}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">22.5</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":30}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">30</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":45}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">45</td><td data-sheets-formula="=R1C2+R[-1]C[0]*R2C2" data-sheets-value="{"1":3,"3":60}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">60</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"VM price"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">VM price USD</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":15000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">15000</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":30000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">30000</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":45000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">45000</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":90000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">90000</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":180000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">180000</td><td data-sheets-formula="=R[-2]C[0]*R3C2" data-sheets-value="{"1":3,"3":270000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">270000</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"LM days"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">LM days</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":30}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">30</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":60}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">60</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":90}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">90</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":180}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">180</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":360}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">360</td><td data-sheets-formula="=R[-3]C[0]*R4C2" data-sheets-value="{"1":3,"3":540}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">540</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"LM price"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">LM price USD</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":12500}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">12500</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":25000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">25000</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":37500}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">37500</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":75000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">75000</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":150000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">150000</td><td data-sheets-formula="=R[-4]C[0]*R5C2" data-sheets-value="{"1":3,"3":225000}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); padding: 2px 3px; text-align: right; vertical-align: bottom;">225000</td></tr>
<tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"Price for a day"}" style="border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); font-weight: bold; padding: 2px 3px; vertical-align: bottom;">Price for a day saved in USD</td><td data-sheets-formula="= ROUND ((R[-3]C[0]-R[-1]C[0])/ IF((R[-2]C[0]-R[-4]C[0])>0,R[-2]C[0]-R[-4]C[0],1))" data-sheets-value="{"1":3,"3":200}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">200</td><td data-sheets-formula="= ROUND ((R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0]))" data-sheets-value="{"1":3,"3":125}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">125</td><td data-sheets-formula="= ROUND((R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0]))" data-sheets-value="{"1":3,"3":111}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">111</td><td data-sheets-formula="= (R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0])" data-sheets-value="{"1":3,"3":100}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">100</td><td data-sheets-formula="= ROUND ((R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0]))" data-sheets-value="{"1":3,"3":95}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">95</td><td data-sheets-formula="= ROUND ((R[-3]C[0]-R[-1]C[0])/ (R[-2]C[0]-R[-4]C[0]))" data-sheets-value="{"1":3,"3":94}" style="border-bottom-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); color: red; font-weight: bold; padding: 2px 3px; text-align: right; vertical-align: bottom;">94</td></tr>
</tbody></table>
<br />
<h3>
Na závěr</h3>
Samozřejmě jsou i jiné důvody pro zavedení práce s VM - firma to může striktně vyžadovat, přeci jen tak může lépe kontrolovat přístup ke zdrojovým kódům, popřípadě je přidané hodnota práce tak zásadní, že zvýšené náklady nejsou podstatné. navíc si může sama provozovat prostředí pro běh VM a v kombinaci s ostatními faktory se to pak vyplatí.</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com12tag:blogger.com,1999:blog-2993762679677061763.post-72770447463127842762017-07-19T13:36:00.002+02:002017-07-19T13:42:18.972+02:00StreamReader nebo ReadAll<div style="text-align: left;">
<a href="https://upload.wikimedia.org/wikipedia/commons/d/db/Employee_performance.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="Výsledek obrázku pro performance" border="0" height="72" src="https://upload.wikimedia.org/wikipedia/commons/d/db/Employee_performance.jpg" width="320" /></a>V miniseriálu o funkcionálním programování jsem se zabýval zpracováním CSV souboru. Soubor, tedy textový dokument, jakým je CSV, můžeme v zásadě zpracovávat dvěma způsoby: vše načíst do paměti a nebo využít stream.</div>
<div style="text-align: justify;">
</div>
<a name='more'></a><br />
<br />
<div style="text-align: justify;">
Tedy buď: </div>
<br />
<span style="color: blue; font-family: "courier new" , "courier" , monospace;">var lines = File.ReadAllLines(fileName);<br />foreach (var line in lines)<br />{</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: blue;"> ...</span><br /> </span><br />
a nebo <br />
<br />
<br />
<span style="color: blue; font-family: "courier new" , "courier" , monospace;">using (var reader = new StreamReader(fileName))<br />{<br /> while ((line = reader.ReadLine()) != null)<br /> {<br /> ...</span><span style="font-family: "arial"; font-size: 14pt; vertical-align: baseline; white-space: pre-wrap;"><br /></span>
<br />
<div style="text-align: justify;">
Každý z těchto přístupů má své pro a proti a rozdíly vyniknou zejména při zpracování velkých souborů, například zpracování CSV s cca jedním miliónem řádků o velikosti cca 800 MB vypadá takto:</div>
<br />
Pro ReadAllLines:<br />
<div style="text-align: center;">
<img height="98px;" src="https://lh6.googleusercontent.com/Ifyuc8dELcQQoWUBWmwrb-iaStUTE9qfUL7UNaA8LiDs4iqg4KaMpEi2fXeHJGLx-EZUSAZkiCW2BZJR9FL3tMkZ5Wm4Tq7Mer1kzLykKfxw-I_Joy-VTQSLGAQrZfOqfR4zUpP6al8" width="482px;" /></div>
</div>
<div>
<br /></div>
<div>
Pro StreamReader:</div>
<div style="text-align: right;">
<div style="text-align: center;">
<span id="docs-internal-guid-d90ed345-5a9a-b3a6-160d-22301032c58f"><img height="88px;" src="https://lh6.googleusercontent.com/czb3H3_6mwWWupBW5zq8kY3hUczrPnws695qCAfzT4wXwvlm_FN9SRNYQM8k1_C2zoBl2_MTDGfwumO6URPG1e2k2sFjWlqg9ZtrfpHCPTDdikCKEshOAQsG6Z61d7Aqbt4Tfns79dA" width="491px;" /></span></div>
</div>
<div>
<br /></div>
<div>
<div style="text-align: justify;">
Čtení po řádcích, tedy s využítím StreamReaeru, znamená citelně menší zabranou paměť, čas nutný na přečtení souboru je ale o cca 5-10% delší než pro ReadAllLines. Ovšem tam za toto zrychlení platíme pamětí, které je potřeba cca 9-krát více.</div>
<br />
<div style="text-align: justify;">
Samozřejmě že u malých, běžně zpracovávaných souborů, je to skoro jedno, ale pokud potřebujeme zpracovat delší soubor, je dobré vědět o těchto rozdílech.</div>
</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com2tag:blogger.com,1999:blog-2993762679677061763.post-23562784158617204492017-07-16T12:23:00.002+02:002017-07-17T11:29:11.400+02:00Funkcionální programování potřetí<div class="" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJoBoqhqcsu3OYK-R_2z9XOeUZopZUZoZ0XFdiEjQ1b5jza5vIrhfYLsHO6WJ_LbEqlArzWh0MZ_dr2S9xd4ZqJSe6vdnOE_FFLrfWd5HQs0_k5VrglQ4d1RTlEDt8IVgIV7gDEb6bi64/s1600/IMG_20170707_161433.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJoBoqhqcsu3OYK-R_2z9XOeUZopZUZoZ0XFdiEjQ1b5jza5vIrhfYLsHO6WJ_LbEqlArzWh0MZ_dr2S9xd4ZqJSe6vdnOE_FFLrfWd5HQs0_k5VrglQ4d1RTlEDt8IVgIV7gDEb6bi64/s200/IMG_20170707_161433.jpg" width="200" /></a></div>
<div style="text-align: justify;">
Výsledný kód programu, využívajícího funkcionální přístup ke zpracování CSV souboru v<a href="https://martinstrimpfl.blogspot.cz/2017/06/funkcionalni-programovani-podruhe.html"> předešlém příspěvku</a>, byl trochu kostrbatý a špatně čitelný. Obsahoval příliš mnoho podmínek <b>if</b>.</div>
<br />
<br />
<div style="text-align: justify;">
Těm se lze vyhnout, pokud použijeme takzvaný<b><i> railway</i></b> přístup k zápisu kódu. Při tomto přístupu se na funkci díváme jako na kus kolejiště s výhybkou a na spuštěný kód jako na vláček, který po sestaveném kolejišti jede.</div>
<a name='more'></a><br />
<br />
<div style="text-align: justify;">
Pokud je funkce vykonána v pořádku, pokračuje vláček, tedy náš kód, rovně. Pokud dojde k chybě, přehodí se výhybka a vláček pokračuje po vedlejší koleji a už se nikdy nemůže vrátit na původní směr.</div>
<br />
Zjednodušený pohled na funkci je pak takovýto:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh3VouAFUUO-_I5aCOaAWPPZ5hFMtC_KEXkxSdkMpiL6Z4Z3WwIcwd2xZrD2wDmmFWIJoPCW78eWGldFrwH5RMqFsoWWknQBpFILvKTPm4iSjellNuVUxgu2fRrN0u8L71Wvil2bKc0VQ/s1600/train.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="93" data-original-width="294" height="63" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh3VouAFUUO-_I5aCOaAWPPZ5hFMtC_KEXkxSdkMpiL6Z4Z3WwIcwd2xZrD2wDmmFWIJoPCW78eWGldFrwH5RMqFsoWWknQBpFILvKTPm4iSjellNuVUxgu2fRrN0u8L71Wvil2bKc0VQ/s200/train.png" width="200" /></a></div>
<br />
A celkový běh programu pak lze graficky vyjádřit takto:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKI5Z7pY6_57LXw1PsUkw1VdNK4YheoPv3sUkUWWBheu3S7F0emjBk26AGJeXPcd0_RHXUVh3w_P1IZ69sQD86CCAIfqBdTs9aZQKzo0Y7yAioRafoRYHLGSW_ICCATxk7A16-M_t02rs/s1600/TrailTwo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="230" data-original-width="1268" height="115" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKI5Z7pY6_57LXw1PsUkw1VdNK4YheoPv3sUkUWWBheu3S7F0emjBk26AGJeXPcd0_RHXUVh3w_P1IZ69sQD86CCAIfqBdTs9aZQKzo0Y7yAioRafoRYHLGSW_ICCATxk7A16-M_t02rs/s640/TrailTwo.png" width="640" /></a></div>
<br />
<div style="text-align: justify;">
Abychom byli schopni toto přenést do kódu, je nutné doplnit metodu <b><i>onsuccess</i></b> - stavem <b><i>onfailure</i></b> se nebudu zabývat, ale implementace by byla analogická a více informací a tipů naleznete v odkazech v první části tohoto miniseriálu - obvykle se implementují ještě metody <b>OnFailure</b> and <b>OnBoth</b>.</div>
<br />
<!--START--><br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">ResultExtensions</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">TOut</span><span class="punctuation">></span> <span class="identifier">OnSuccess</span><span class="punctuation"><</span><span class="type parameter name" style="color: #2b91af;">T</span><span class="punctuation">,</span> <span class="type parameter name" style="color: #2b91af;">TOut</span><span class="punctuation">>(</span><span class="keyword" style="color: blue;">this</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">></span> <span class="identifier">result</span><span class="punctuation">,</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">,</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">TOut</span><span class="punctuation">>></span> <span class="identifier">func</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier">result</span><span class="operator">.</span><span class="identifier">IsFailure</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span><span class="operator">.</span><span class="identifier">Fail</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">TOut</span><span class="punctuation">>(</span><span class="identifier">result</span><span class="operator">.</span><span class="identifier">Error</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">func</span><span class="punctuation">(</span><span class="identifier">result</span><span class="operator">.</span><span class="identifier">Value</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span> <span class="identifier">OnSuccess</span><span class="punctuation"><</span><span class="type parameter name" style="color: #2b91af;">T</span><span class="punctuation">>(</span><span class="keyword" style="color: blue;">this</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">></span> <span class="identifier">result</span><span class="punctuation">,</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">,</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span><span class="punctuation">></span> <span class="identifier">func</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier">result</span><span class="operator">.</span><span class="identifier">IsFailure</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span><span class="operator">.</span><span class="identifier">Fail</span><span class="punctuation">(</span><span class="identifier">result</span><span class="operator">.</span><span class="identifier">Error</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">func</span><span class="punctuation">(</span><span class="identifier">result</span><span class="operator">.</span><span class="identifier">Value</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<!--END-->
A původní funkci můžeme přepsat na:<br />
<br />
<!--START--><br />
<pre><code>
<span class="keyword" style="color: blue;">public</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Result</span> <span class="identifier">ProcessLine</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">int</span> <span class="identifier">number</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span> <span class="identifier">content</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">headerInfoAction</span><span class="operator">.</span><span class="identifier">Execute</span><span class="punctuation">(</span><span class="identifier">number</span><span class="punctuation">,</span> <span class="identifier">content</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">OnSuccess</span><span class="punctuation">(</span>
<span class="identifier">headerInfo</span> <span class="operator">=></span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">parser</span><span class="operator">.</span><span class="identifier">ParseToDictionary</span><span class="punctuation">(</span><span class="identifier">headerInfo</span><span class="punctuation">,</span> <span class="identifier">content</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">OnSuccess</span><span class="punctuation">(</span>
<span class="identifier">parsedLine</span> <span class="operator">=></span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">lineIdProvider</span><span class="operator">.</span><span class="identifier">GetLineId</span><span class="punctuation">(</span><span class="identifier">parsedLine</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">OnSuccess</span><span class="punctuation">(</span>
<span class="identifier">id</span> <span class="operator">=></span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">duplicateChecker</span><span class="operator">.</span><span class="identifier">CanProcessLine</span><span class="punctuation">(</span><span class="identifier">id</span><span class="punctuation">,</span> <span class="identifier">number</span><span class="punctuation">);</span>
<span class="punctuation">});</span>
<span class="punctuation">});</span>
<span class="punctuation">});</span>
<span class="punctuation">}</span></code>
</pre>
<!--END-->
Kód je kratší a lépe čitelný. Na závěr ještě jednou seznam odkazů na více informací:<br />
<br />
<a href="https://app.pluralsight.com/library/courses/csharp-applying-functional-principles">https://app.pluralsight.com/library/courses/csharp-applying-functional-principles</a> <br />
<a href="http://enterprisecraftsmanship.com/">http://enterprisecraftsmanship.com/</a><br />
<a href="https://github.com/vkhorikov">https://github.com/vkhorikov</a><a href="https://www.nuget.org/packages/CSharpFunctionalExtensions">https://www.nuget.org/packages/CSharpFunctionalExtensions</a>mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com18tag:blogger.com,1999:blog-2993762679677061763.post-85911872657279004832017-06-22T09:57:00.000+02:002017-06-22T10:00:42.125+02:00Funkcionální programování podruhé<br />
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAXMYzoj-KBjfBD28jkMK8hdMOM7LH7aStA09mOPv5O0Eo5Xre7xLUs_gWTGYHl-Pya0n1-4gfKS5EsOXE1hXVQBEN_rnBn0BJU3LdJ6u6NFwT8TpkdX5lsJYYgUqMrvhELRpWeXtyO5g/s1600/Csv.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 5em;"><img border="0" data-original-height="146" data-original-width="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAXMYzoj-KBjfBD28jkMK8hdMOM7LH7aStA09mOPv5O0Eo5Xre7xLUs_gWTGYHl-Pya0n1-4gfKS5EsOXE1hXVQBEN_rnBn0BJU3LdJ6u6NFwT8TpkdX5lsJYYgUqMrvhELRpWeXtyO5g/s1600/Csv.png" /></a></div>
Jak implementovat funkcionální přístup ukážu na jednoduchém validátoru CSV souboru. Je to poměrně jednoduchá úloha s těmito třemi zásadními operacemi:</div>
<br />
<ul>
<li>z prvního řádku je nutné získat seznam sloupců</li>
<li>z následujících pak</li>
<ul>
<li>získat seznam hodnot název sloupce - hodnota</li>
<li>jeden ze sloupců obsahuje primární klíč, duplicitní řádky tedy musíme vyloučit</li>
</ul>
</ul>
<a name='more'></a><br />
<br />
<div style="text-align: justify;">
Jak by třeba vypadala třída na kontrolu duplicity řádka před zavedením <b>Result</b>? Nemusí to být nic světoborného, prostě si zapamatujeme, co jsme už zpracovali a podle toho zpracování dat povolíme a nebo ne:</div>
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">DuplicateChecker</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">int</span>> map = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">int</span>>();
<span style="color: blue;">bool</span> CanProcessLine(<span style="color: blue;">string</span> id, <span style="color: blue;">int</span> lineNumber)
{
<span style="color: blue;">if</span> (map.ContainsKey(id))
{
<span style="color: blue;">var</span> processedLine = map[id];
<span style="color: blue;">if</span> (processedLine != lineNumber)
{
<span style="color: blue;">return</span> <span style="color: blue;">false</span>;
}
}
<span style="color: blue;">else</span>
{
map.Add(id, lineNumber);
}
<span style="color: blue;">return</span> <span style="color: blue;">true</span>;
}
}</pre>
<br />
<div style="text-align: justify;">
Myslím, že princip je vcelku jednoduchý. Ale vřele doporučuji shlédnout nějaké video od pána, co se jmenuje <a href="http://www.curbralan.com/">Kevlin Henney</a> a zjistíme, že vše lze zlepšit. Pro inspiraci nabízím například tento záznam jeho přednášky z IIT 2016: </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/ZsHMHukIlJY/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/ZsHMHukIlJY?feature=player_embedded" width="320"></iframe></div>
<br />
<div style="text-align: center;">
<i>zdroj: <a href="https://www.youtube.com/watch?v=ZsHMHukIlJY">https://www.youtube.com/watch?v=ZsHMHukIlJY</a></i></div>
<br />
A třídu pak můžeme upravit takto:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Condition</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">int</span>> alreadyProcessLines = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">int</span>>();
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> LineHasNotBeenProcessed(<span style="color: blue;">string</span> id, <span style="color: blue;">int</span> lineNumber)
{
<span style="color: blue;">if</span> (alreadyProcessLines.ContainsKey(id))
{
<span style="color: blue;">var</span> processedLineNumberWithSameId = alreadyProcessLines[id];
<span style="color: blue;">if</span> (processedLineNumberWithSameId != lineNumber)
{
<span style="color: blue;">return</span> <span style="color: blue;">false</span>;
}
}
<span style="color: blue;">else</span>
{
alreadyProcessLines.Add(id, lineNumber);
}
<span style="color: blue;">return</span> <span style="color: blue;">true</span>;
}
}</pre>
<br />
Do projektu nyní přidám třídu <b>Result </b>a pomocné metody pro usnadnění práce:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Result</span>
{
<span style="color: blue;">protected</span> Result(<span style="color: blue;">bool</span> isSuccess, <span style="color: blue;">string</span> error)
{
<span style="color: blue;">if</span> (isSuccess && !<span style="color: blue;">string</span>.IsNullOrWhiteSpace(error))
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>();
}
<span style="color: blue;">if</span> (!isSuccess && <span style="color: blue;">string</span>.IsNullOrWhiteSpace(error))
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>();
}
IsSuccess = isSuccess;
Error = error;
}
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsSuccess { <span style="color: blue;">get</span>; }
<span style="color: blue;">public</span> <span style="color: blue;">string</span> Error { <span style="color: blue;">get</span>; <span style="color: blue;">private</span> <span style="color: blue;">set</span>; }
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsFailure => !IsSuccess;
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Result</span> Fail(<span style="color: blue;">string</span> message)
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Result</span>(<span style="color: blue;">false</span>, message);
}
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Result</span> Fail(<span style="color: blue;">string</span> format, <span style="color: blue;">params</span> <span style="color: blue;">object</span>[] args)
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Result</span>(<span style="color: blue;">false</span>, <span style="color: blue;">string</span>.Format(<span style="color: #2b91af;">CultureInfo</span>.InvariantCulture, format, args));
}
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Result</span> Ok()
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Result</span>(<span style="color: blue;">true</span>, <span style="color: blue;">string</span>.Empty);
}
}</pre>
<br />
A původní metodu přepíšu tak, aby vracela instanci této nové třídy místo původní <b><i>boolean </i></b> hodnoty:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Condition</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">int</span>> alreadyProcessLines = <span style="color: blue;">new</span> <span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">int</span>>();
<span style="color: blue;">public</span> <span style="color: #2b91af;">Result</span> LineHasNotBeenProcessed(<span style="color: blue;">string</span> id, <span style="color: blue;">int</span> lineNumber)
{
<span style="color: blue;">if</span> (alreadyProcessLines.ContainsKey(id))
{
<span style="color: blue;">var</span> processedLineNumberWithSameId = alreadyProcessLines[id];
<span style="color: blue;">if</span> (processedLineNumberWithSameId != lineNumber)
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail(
<span style="color: #a31515;">"Line duplicated. Line #{1} processed instead"</span>,
lineNumber,
processedLineNumberWithSameId);
}
}
<span style="color: blue;">else</span>
{
alreadyProcessLines.Add(id, lineNumber);
}
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Ok();
}
}</pre>
<br />
<br />
<div style="text-align: justify;">
Ve stejném duchu si napíši i ostatní metody nutné pro zpracování souboru - ale protože si už nevystačím jen s prostým návratovým typem, je nutné přidat i generickou podobu třídy <b>Result</b>:</div>
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">T</span>> : <span style="color: #2b91af;">Result</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">T</span> value;
<span style="color: blue;">protected</span> <span style="color: blue;">internal</span> Result(<span style="color: #2b91af;">T</span> value, <span style="color: blue;">bool</span> isSuccess, <span style="color: blue;">string</span> error) : <span style="color: blue;">base</span>(isSuccess, error)
{
<span style="color: blue;">this</span>.value = value;
}
<span style="color: blue;">public</span> <span style="color: #2b91af;">T</span> Value
{
<span style="color: blue;">get</span>
{
<span style="color: blue;">if</span> (!IsSuccess)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>();
}
<span style="color: blue;">return</span> value;
}
}
}</pre>
<br />
A do původní třídy <b>Result </b>přidáme tyto statické metody, které usnadní vytváření nových generických instancí:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">T</span>> Fail<<span style="color: #2b91af;">T</span>>(<span style="color: blue;">string</span> message)
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">T</span>>(<span style="color: blue;">default</span>(<span style="color: #2b91af;">T</span>), <span style="color: blue;">false</span>, message);
}
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">T</span>> Fail<<span style="color: #2b91af;">T</span>>(<span style="color: blue;">string</span> format, <span style="color: blue;">params</span> <span style="color: blue;">object</span>[] args)
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">T</span>>(<span style="color: blue;">default</span>(<span style="color: #2b91af;">T</span>), <span style="color: blue;">false</span>, <span style="color: blue;">string</span>.Format(<span style="color: #2b91af;">CultureInfo</span>.InvariantCulture, format, args));
}
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">T</span>> Ok<<span style="color: #2b91af;">T</span>>(<span style="color: #2b91af;">T</span> value)
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">T</span>>(value, <span style="color: blue;">true</span>, <span style="color: blue;">string</span>.Empty);
}</pre>
<br />
<div style="text-align: justify;">
A tedy pro zpracování řádku z CSV souboru si zatím můžeme vystačit s touto třídou - jen upozornění, tohle je značně zjednodušený způsob zpracování, ve skutečnosti může být řádek v CSV souboru složitější a s pouhým splitem si nelze vystačit. </div>
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">LineParser</span>
{
<span style="color: blue;">public</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>>> ToList(<span style="color: blue;">string</span> content)
{
<span style="color: blue;">if</span> (<span style="color: blue;">string</span>.IsNullOrEmpty(content))
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail<<span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>>>(<span style="color: #a31515;">"Line cannot be empty or null"</span>);
}
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Ok(content.Split(<span style="color: #a31515;">','</span>).ToList());
}
<span style="color: blue;">public</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">string</span>>> ToDictionary(<span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>> header, <span style="color: blue;">string</span> content)
{
<span style="color: blue;">var</span> parsingResult = ToList(content);
<span style="color: blue;">if</span> (parsingResult.IsFailure)
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail<<span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">string</span>>>(parsingResult.Error);
}
<span style="color: blue;">if</span> (parsingResult.Value.Count != header.Count)
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail<<span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">string</span>>>(<span style="color: #a31515;">"Cannot parse to columns"</span>);
}
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Ok(header.Select((s, i) => <span style="color: blue;">new</span> { s, i }).ToDictionary(x => x.s, x => parsingResult.Value[x.i]));
}
}</pre>
<br />
Seznam názvů sloupců z prvního řádku drží zase instance této třídy:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">HeaderColumnNamesProvider</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">LineParser</span> lineParser = <span style="color: blue;">new</span> <span style="color: #2b91af;">LineParser</span>();
<span style="color: blue;">private</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>>> headerNames;
<span style="color: blue;">public</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>>> Get(<span style="color: blue;">int</span> number, <span style="color: blue;">string</span> content)
{
<span style="color: blue;">if</span> (headerNames == <span style="color: blue;">null</span>)
{
<span style="color: blue;">if</span> (number == 1)
{
headerNames = lineParser.ToList(content);
}
<span style="color: blue;">else</span>
{
headerNames = <span style="color: #2b91af;">Result</span>.Fail<<span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>>>(<span style="color: #a31515;">"Only first line can be used as header"</span>);
}
}
<span style="color: blue;">return</span> headerNames;
}
}</pre>
<br />
a nakonec ještě kód pro získání jedinečného identifikátoru ze seznamu hodnot na řádku CSV souboru:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">IdentityProvider</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: blue;">string</span> identityColumnName = <span style="color: #a31515;">"Id"</span>;
<span style="color: blue;">public</span> <span style="color: #2b91af;">Result</span><<span style="color: blue;">string</span>> Get(<span style="color: #2b91af;">Dictionary</span><<span style="color: blue;">string</span>, <span style="color: blue;">string</span>> columnNameValues)
{
<span style="color: blue;">if</span> (columnNameValues.ContainsKey(identityColumnName))
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Ok(columnNameValues[identityColumnName]);
}
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail<<span style="color: blue;">string</span>>(<span style="color: #a31515;">"No column {0} present."</span>, identityColumnName);
}
}</pre>
<br />
<br />
A pokud se to vše dá dohromady v další třídě, která zpracuje řádek, dopadne to takhle:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">LineAction</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">HeaderColumnNamesProvider</span> headerColumNamesProvider = <span style="color: blue;">new</span> <span style="color: #2b91af;">HeaderColumnNamesProvider</span>();
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">IdentityValueProvider</span> identityProvider = <span style="color: blue;">new</span> <span style="color: #2b91af;">IdentityValueProvider</span>();
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Condition</span> recurrenceCondition = <span style="color: blue;">new</span> <span style="color: #2b91af;">Condition</span>();
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">LineParser</span> parser = <span style="color: blue;">new</span> <span style="color: #2b91af;">LineParser</span>();
<span style="color: blue;">public</span> <span style="color: #2b91af;">Result</span> ProcessLine(<span style="color: blue;">int</span> number, <span style="color: blue;">string</span> content)
{
<span style="color: blue;">var</span> headerInfoActionResult = headerColumNamesProvider.Get(number, content);
<span style="color: blue;">if</span> (headerInfoActionResult.IsFailure)
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail(headerInfoActionResult.Error);
}
<span style="color: blue;">var</span> parsingResult = parser.ToDictionary(headerInfoActionResult.Value, content);
<span style="color: blue;">if</span> (parsingResult.IsFailure)
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail(parsingResult.Error);
}
<span style="color: blue;">var</span> lineIdResult = identityProvider.Get(parsingResult.Value);
<span style="color: blue;">if</span> (lineIdResult.IsFailure)
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail(lineIdResult.Error);
}
<span style="color: blue;">var</span> duplicateCheckerResult = recurrenceCondition.LineHasNotBeenProcessed(lineIdResult.Value, number);
<span style="color: blue;">if</span> (duplicateCheckerResult.IsFailure)
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail(duplicateCheckerResult.Error);
}
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Ok();
}
</pre>
<br />
a to vše zavoláme z metody <b>Main,</b> tedy za předpokladu, že pracujeme na konzolové aplikaci:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args)
{
ProcessFile(<span style="color: maroon;">@"D:\Temp\TestImport\Import_100.txt"</span>);
<span style="color: #2b91af;">Console</span>.ReadLine();
}
<span style="color: blue;">static</span> <span style="color: blue;">void</span> ProcessFile(<span style="color: blue;">string</span> fileName)
{
<span style="color: blue;">string</span> line;
<span style="color: blue;">int</span> lineNumber = 0;
<span style="color: blue;">var</span> lineProcessor = <span style="color: blue;">new</span> <span style="color: #2b91af;">LineAction</span>();
<span style="color: blue;">var</span> result = <span style="color: #2b91af;">Result</span>.Ok();
<span style="color: blue;">using</span> (<span style="color: blue;">var</span> reader = <span style="color: blue;">new</span> <span style="color: #2b91af;">StreamReader</span>(fileName))
{
<span style="color: blue;">while</span> ((line = reader.ReadLine()) != <span style="color: blue;">null</span> && result.IsSuccess)
{
result = lineProcessor.ProcessLine(++lineNumber, line);
}
}
<span style="color: blue;">if</span> (result.IsSuccess)
{
<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"File is ok"</span>);
}
<span style="color: blue;">else</span>
{
<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"File is wrong: {0}"</span>, result.Error);
}
}</pre>
<br />
<div style="text-align: justify;">
Zatím jsem jen napsal hromadu kódu a nijak ohromně to zatím nevypadá - ale v dalším pokračování provedu pár úprav a výhody funkcionálního přístup vyniknou více. Už nyní je výhoda,že pokud dojde k nějakému problému, je v chybové hlášce řečeno k jakému.</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-1809206523920565012017-06-20T10:21:00.000+02:002017-06-20T10:23:00.677+02:00Zmatky v práci s AD<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFCRmxyObbO3FavFYGeeGWS40Pu69a0FlKhiiN42IL81TDExZQ3GZ2YYkEd1szcSgLfWIQQ3B5wRkyvsW4D980VsWb-5wTmuik3CpRHmSLUdYeWQJFIzRETvyZTbkbG1XjkOEvK_uCGgw/s1600/MSAD.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="116" data-original-width="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFCRmxyObbO3FavFYGeeGWS40Pu69a0FlKhiiN42IL81TDExZQ3GZ2YYkEd1szcSgLfWIQQ3B5wRkyvsW4D980VsWb-5wTmuik3CpRHmSLUdYeWQJFIzRETvyZTbkbG1XjkOEvK_uCGgw/s1600/MSAD.png" /></a></div>
Active Directory je Microsoftí implementace adresářových služeb LDAP. A jak je MS dobrým zvykem, pokud chce programátor s touto službou spolupracovat, může si vybrat hned z několika možností.<br />
Ty se navíc liší výkonem a možnostmi, takže je zkrátka asi nejlepší vědět a znát všechny - vždy mne překvapuje, jak i firma velikosti MS nedokáže dotáhnout některé věci k použitelnému stavu.<br />
<br />
<br />
<a name='more'></a><br />
Původně nabízel Microsoft pro práci s AD ADSI, Active Directory Service Interface.<br />
<br />
S nástupem .NET pak nabídl <b>System.DirectoryServices</b>, které jsou vlastně jen obálkou pro ADSI, výhodou je, že mohou pracovat vůčši jakémukoliv LDAP serveru, tedy ne jen s AD. Nevýhodou pak, že neexistují žádné typově silné objekty.<br />
<br />
Při příchodu .NET 2.0 nabídl MS knihovnu <b>System.DirectoryServices.Protocols</b>. Nabízí lepší výkon, neboť to už není wrapper nad ADSI, ale použití je složitější.<br />
<br />
Proto s .NET 3.5 představil MS další knihovnu,<b> System.DirectoryServices.AccountManagement</b>, která si vystačí s třemi základními objekty User, Group, Computer a pracuje jen s AD. Je ještě o trochu rychlejší než předchozí knihovna a je na ní postaven i module AcitveDirectory pro PowerShell.<br />
<br />
<br />
Takže programátorovi v .NET se nabízí hned tři různé knihovny pro práci s AD, navíc se ty knihovny liší co do možností a výkonu.<br />
<br />
Tady je například srovnání kódu pro ověření přihlašovacích údajů uživatele - tedy uživatelského jména a hesla:<br />
<br />
S použitím <b>System.DirectoryServices</b>:<br />
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsAuthenticated(<span style="color: blue;">string</span> username, <span style="color: blue;">string</span> password)
{
<span style="color: blue;">const</span> <span style="color: blue;">string</span> LDAPSERVER = <span style="color: #a31515;">"dc.somedomain.somewhere"</span>;
<span style="color: blue;">using</span> (<span style="color: #2b91af;">DirectoryEntry</span> root = <span style="color: blue;">new</span> <span style="color: #2b91af;">DirectoryEntry</span>(
<span style="color: #a31515;">"LDAP:/"</span> + LDAPSERVER,
username,
password,
<span style="color: #2b91af;">AuthenticationTypes</span>.Secure))
{
<span style="color: blue;">const</span> <span style="color: blue;">int</span> ERROR_LOGON_FAILURE = -2147023570;
<span style="color: blue;">try</span>
{
<span style="color: blue;">object</span> tmp = root.NativeGuid;
<span style="color: blue;">return</span> <span style="color: blue;">true</span>;
}
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">COMException</span> exception) <span style="color: blue;">when</span> (exception.ErrorCode == ERROR_LOGON_FAILURE)
{
<span style="color: blue;">return</span> <span style="color: blue;">false</span>;
}
}
}</pre>
<br />
a tady s použitím <b>System.DirectoryServices.Protocols</b>:
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsAuthenticated(<span style="color: blue;">string</span> username, <span style="color: blue;">string</span> password)
{
<span style="color: blue;">const</span> <span style="color: blue;">string</span> LDAPSERVER = <span style="color: #a31515;">"dc.somedomain.somewhere"</span>;
<span style="color: blue;">var</span> directoryId = <span style="color: blue;">new</span> <span style="color: #2b91af;">LdapDirectoryIdentifier</span>(LDAPSERVER, 636);
<span style="color: blue;">var</span> networkCredential = <span style="color: blue;">new</span> System.Net.<span style="color: #2b91af;">NetworkCredential</span>(username, password);
<span style="color: blue;">using</span> (<span style="color: blue;">var</span> ldapConnection = <span style="color: blue;">new</span> <span style="color: #2b91af;">LdapConnection</span>(directoryId, networkCredential, <span style="color: #2b91af;">AuthType</span>.Basic))
{
ldapConnection.AutoBind = <span style="color: blue;">false</span>;
ldapConnection.Timeout = <span style="color: blue;">new</span> <span style="color: #2b91af;">TimeSpan</span>(0, 0, 0, 300);
ldapConnection.SessionOptions.SecureSocketLayer = <span style="color: blue;">true</span>;
ldapConnection.SessionOptions.VerifyServerCertificate = <span style="color: blue;">delegate</span> { <span style="color: blue;">return</span> <span style="color: blue;">true</span>; };
ldapConnection.SessionOptions.ProtocolVersion = 3;
<span style="color: blue;">try</span>
{
<span style="color: green;">// Bind makes the connection and validates the credentials. </span>
<span style="color: green;">// Any failure results in a LdapException being thrown.</span>
ldapConnection.Bind();
<span style="color: blue;">return</span> <span style="color: blue;">true</span>;
}
<span style="color: blue;">catch</span>(<span style="color: #2b91af;">LdapException</span>)
{
<span style="color: blue;">return</span> <span style="color: blue;">false</span>;
}
}
}</pre>
<br />
a nakonec totéž s <b>System.DirectoryServies.AccountManagement</b> objektů:
<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">bool</span> IsAuthenticated(<span style="color: blue;">string</span> username, <span style="color: blue;">string</span> password)
{
<span style="color: blue;">const</span> <span style="color: blue;">string</span> LDAPSERVER = <span style="color: #a31515;">"</span>dc.somedomain.somewhere";
<span style="color: blue;">using</span> (<span style="color: blue;">var</span> context = <span style="color: blue;">new</span> <span style="color: #2b91af;">PrincipalContext</span>(<span style="color: #2b91af;">ContextType</span>.Domain, LDAPSERVER))
{
<span style="color: blue;">return</span> context.ValidateCredentials(
username,
password,
<span style="color: #2b91af;">ContextOptions</span>.SecureSocketLayer | <span style="color: #2b91af;">ContextOptions</span>.SimpleBind);
}
}</pre>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com2tag:blogger.com,1999:blog-2993762679677061763.post-52426605173253243652017-06-17T19:52:00.000+02:002017-06-18T12:00:15.835+02:00Funkcionální programování<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4GAzo371ZG6QjADCCpbpGZVBfgs9bcXOqTldAz3KiNX7kP8Q1_bCS_XTerYajzmSw3TWoyOQBlniJHxnpmEnnx23lDISfzP-qI1joUUXpqGwS7-WHCRvdhoDhkvu59VENBoflSWfPx_I/s1600/funcional.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="400" data-original-width="400" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4GAzo371ZG6QjADCCpbpGZVBfgs9bcXOqTldAz3KiNX7kP8Q1_bCS_XTerYajzmSw3TWoyOQBlniJHxnpmEnnx23lDISfzP-qI1joUUXpqGwS7-WHCRvdhoDhkvu59VENBoflSWfPx_I/s200/funcional.png" width="200" /></a></div>
V poslední době jsem začal více využívat ve svém kódu principy funkcionálního programování. Zčásti to začalo použitím vzoru <a href="http://martinstrimpfl.blogspot.com/2016/01/maybe-navrhovy-vzor.html">Maybe</a>, ale rozvinul jsem to dále a zkušenost to byla tak dobrá, že se o ní podělím.<br />
<br />
<div>
Hned na začátek pro ty, co mají přístup ke kurzům na pluralsight, uvádím odkaz na dobrý kurz, který vše pěkně dopodrobna vysvětluje - <a href="https://app.pluralsight.com/library/courses/csharp-applying-functional-principles/table-of-contents">Applying Functional Principles in C#</a> od Vladimira Khorikova.<br />
<br />
Tento pán má i své <a href="http://enterprisecraftsmanship.com/">vlastní stránky</a><a href="http://enterprisecraftsmanship.com/"> </a>a dostupná je i knihovna s níže <a href="https://www.nuget.org/packages/CSharpFunctionalExtensions">popsanými třídami</a>. </div>
<div>
<br />
<a name='more'></a></div>
<div>
<h3>
Pár základů</h3>
</div>
<div>
U funkcionálního programování se klade důraz na to, co se má udělat místo toho,jak se to má udělat. S funkcionálním přístupem k programování se už asi setkal každý, kdo kdy napsal něco v Linqu.<br />
<br />
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;">employees.Where(e => e.From > 2010).OrderBy(e => e.Firstname);
</pre>
<br />
Tento dotazovací jazyk je typickým příkladem funkcionálního programování, pokud ho používáme, tak říkáme co se má dělat a málokdo se zabývá tím, jak se to vlastně pod pokličkou provádí.</div>
<div>
<h3>
Proč se vlastně funkcionální přístup používá?</h3>
</div>
<div>
K vysvětlení výhod funkcionálního přístupu je nejlepší použít kus nějakého klasického kódu. Třeba tento kód by měl něco uložit:<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">void</span> Save(<span style="color: blue;">object</span> something)
{
<span style="color: blue;">if</span> (something == <span style="color: blue;">null</span>)
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentNullException</span>();
<span style="color: blue;">if</span> (!(something <span style="color: blue;">is</span> <span style="color: blue;">object</span>))
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">ArgumentException</span>();
Storage.Save(something);
}</pre>
<div style="text-align: justify;">
A v tomhle okamžiku začínají problémy. Kdykoliv budeme podobnou funkci volat, nemůžeme si být jistí výsledkem. Může ale nemusí dojít k výjimce a na tu musíme reagovat - a tak vlastně vědomě či nevědomě větvíme tok programu - navíc ošetření výjimky v bloku <b>catch-try</b> připomíná nechvalně známý příkaz <b>go-to</b>....</div>
<div style="text-align: justify;">
Funkcionální přístup se snaží tento problém řešit - metoda by neměla o své funkci lhát a tedy vždy by měla vracet, co slibuje. Výjimka nemá být způsobem, jak upozornit na problém, u funkcionálního přístupu je výjimka něco tak výjimečného, že je nejlepší v tomto případě ukončit raději celou aplikaci.</div>
<div style="text-align: justify;">
Ale před tím, než popíši, jak to vlastně funkcionální programování řeší, stojí za to se vrátit na chvíli k příkladu a podívat, jak ten se s výjimkou popere. Někde ve volacím řetězci nalezneme obvykle nějaký takový kód:<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">string</span> SaveOrReportBug(<span style="color: blue;">object</span> something)
{
<span style="color: blue;">try</span>
{
Save(something);
}
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">ArgumentNullException</span>)
{
<span style="color: blue;">return</span> <span style="color: #a31515;">"Cannot save null"</span>;
}
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">ArgumentException</span>)
{
<span style="color: blue;">return</span> <span style="color: #a31515;">"Wrong type"</span>;
}
<span style="color: blue;">catch</span>
{
<span style="color: blue;">return</span> <span style="color: #a31515;">"Something happened"</span>;
}
<span style="color: blue;">return</span> <span style="color: blue;">string</span>.Empty;
}</pre>
</div>
Výjimka je přeložena na něco lidsky pochopitelného a takto pak prezentována uživateli.<br />
<br />
<div style="text-align: justify;">
Funkcionální programování celý proces jen zkrátí a to zavedením typu <b>Result</b> - pokud metoda proběhne, jak bylo očekáváno (tzv. happy path), tak vrátí true v property <b>IsSuccess </b>, a pokud ne, tak je <b>IsFailure</b> nastaveno na true a v <b>Error </b>lze nalézt chybové hlášením.</div>
<div style="text-align: justify;">
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Result</span>
{
<span style="color: blue;">protected</span> Result(<span style="color: blue;">bool</span> isSuccess, <span style="color: blue;">string</span> error)
{
<span style="color: blue;">if</span> (isSuccess && !<span style="color: blue;">string</span>.IsNullOrWhiteSpace(error))
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>();
}
<span style="color: blue;">if</span> (!isSuccess && <span style="color: blue;">string</span>.IsNullOrWhiteSpace(error))
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>();
}
IsSuccess = isSuccess;
Error = error;
}
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsSuccess { <span style="color: blue;">get</span>; }
<span style="color: blue;">public</span> <span style="color: blue;">string</span> Error { <span style="color: blue;">get</span>; <span style="color: blue;">private</span> <span style="color: blue;">set</span>; }
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsFailure => !IsSuccess;
}</pre>
</div>
<div style="text-align: justify;">
K tomu je možné si napsat extensivní metody, které vytváření objektů tohoto typu zkrátí:<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Result</span> Fail(<span style="color: blue;">string</span> format, <span style="color: blue;">params</span> <span style="color: blue;">object</span>[] args)
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Result</span>(
<span style="color: blue;">false</span>,
<span style="color: blue;">string</span>.Format(
CultureInfo.InvariantCulture,
format,
args));
}
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">Result</span> Ok()
{
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Result</span>(<span style="color: blue;">true</span>, <span style="color: blue;">string</span>.Empty);
}</pre>
</div>
Původní příklad se ze zavedením třídy <b>Result </b>změní a návratový typ se změní z <b>void </b>(nic se nevrací) na <b>Result</b>:<br />
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: #2b91af;">Result</span> Save(<span style="color: blue;">object</span> something)
{
<span style="color: blue;">if</span> (something == <span style="color: blue;">null</span>)
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail(<span style="color: #a31515;">"Cannot save null."</span>);
<span style="color: blue;">if</span> (!(something <span style="color: blue;">is</span> <span style="color: blue;">object</span>))
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail(<span style="color: #a31515;">"Wrong Type"</span>);
<span style="color: blue;">try</span>
{
Storage.Save(something);
}
<span style="color: blue;">catch</span>
{
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Fail(<span style="color: #a31515;">"Cannot save "</span>);
}
<span style="color: blue;">return</span> <span style="color: #2b91af;">Result</span>.Ok();
}</pre>
</div>
<div style="text-align: justify;">
Metody občas i něco vrací, to lze ošetřit zavedením generického typu <b>Result<T> </b>s property <b>Value</b>:</div>
<pre style="background: white; font-family: Consolas; font-size: 13px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Result</span><<span style="color: #2b91af;">T</span>> : <span style="color: #2b91af;">Result</span>
{
<span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">T</span> value;
<span style="color: blue;">protected</span> <span style="color: blue;">internal</span> Result(<span style="color: #2b91af;">T</span> value, <span style="color: blue;">bool</span> isSuccess, <span style="color: blue;">string</span> error)
: <span style="color: blue;">base</span>(isSuccess, error)
{
<span style="color: blue;">this</span>.value = value;
}
<span style="color: blue;">public</span> <span style="color: #2b91af;">T</span> Value
{
<span style="color: blue;">get</span>
{
<span style="color: blue;">if</span> (!IsSuccess)
{
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>();
}
<span style="color: blue;">return</span> value;
}
}
}</pre>
Výhodou funkcionálního přístupu je fakt, že se můžeme spolehnout na to, jak se metoda chová a není nutné vyhledávat si v dokumentaci, jaké výjimky mohou nastat a následně je ošetřovat - metoda se chová skutečně jako funkce a ne jako pseudo funkce, jak je ilustrováno na tomto obrázku:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDhmzkVbEsoZ1Hl7nPpWhCXRdqMU-7L8gWltEHxZx0oy-k2412g5j56HeWaJAUjFpbJVOfJ4tXzQvkgUz2wqFM7rW-eUzwUB0orR5PMDdCzZb0FBLV2daXIQV1qOJyYTdDrDauGt9Dqg4/s1600/funkce.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="276" data-original-width="656" height="134" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDhmzkVbEsoZ1Hl7nPpWhCXRdqMU-7L8gWltEHxZx0oy-k2412g5j56HeWaJAUjFpbJVOfJ4tXzQvkgUz2wqFM7rW-eUzwUB0orR5PMDdCzZb0FBLV2daXIQV1qOJyYTdDrDauGt9Dqg4/s320/funkce.JPG" width="320" /></a></div>
<br />
<h3>
Konflikt s principem CQS?</h3>
Zkratka <b>CQS </b>znamená <b>Command-Query Separation principle </b>a byla takto definována Martinem Fowler (<a href="https://martinfowler.com/bliki/CommandQuerySeparation.html">https://martinfowler.com/bliki/CommandQuerySeparation.html</a>) - ve zkratce se metody dělí na dotazy a na příkazy.<br />
<br />
<ul>
<li>Dotazy vždy něco vrací, ale nemění pozorovatelný stav systému</li>
<li>Příkazy nic nevrací, ale mění pozorovatelný stav systému</li>
</ul>
<br />
Použití funkcionálního přístupu nemusí nutně znamenat popření těchto pravidel, stačí si jen zavést tuto konvenci:<br />
<br />
Command (can’t fail) public void Save(Data data)<br />
Query (can’t fail) public Data GetById(int id)<br />
Command (can fail) public Result Save(Data data)<br />
Query (can fail) public Result<Data> GetById(int id)<br />
<br />
Konkrétní případ implementace funkcionálního programovaní popíšu příště.
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-43345321830084857112016-09-25T19:50:00.000+02:002016-09-25T19:59:35.034+02:00Konfigurace metody<div style="text-align: justify;">
Postupy zmíněné v článcích o konfiguračních souborech - <a href="http://martinstrimpfl.blogspot.com/2016/06/nacteni-objektu-z-konfiguracniho-souboru.html">zde</a> a <a href="http://martinstrimpfl.blogspot.com/2016/08/nacteni-objektu-z-konfiguracniho.html">zde</a> - jsem využil a udělal jsem si knihovnu pro vytvoření objektu a jeho naplnění hodnotami z konfigurace. Nicméně při sepisování požadavků jsem narazil na problém, že předání všech možných kombinací nastavení do objektu, respektive metody) by vedlo k mnoha přetížením dané metody a celkově obtížnější orientaci v kódu (používám Code Analysis a tedy nejde jen tak použít nepovinné parametry, metoda se musí přetížit). </div>
<div style="text-align: justify;">
</div>
<a name='more'></a><span style="text-align: justify;">Konkrétně jsem chtěl nastavit:</span><br />
<span style="text-align: justify;"><br /></span>
<br />
<div style="text-align: justify;">
</div>
<ul>
<li>zdroj konfiguračních dat, například jestli budou z konfiguračního souboru, ze Service Fabric konfigurace apod</li>
<li>které vlastnosti nenastavovat,</li>
<li>a které naopak nastavit</li>
<li>jak je mapovat na určitý klíč v konfiguraci</li>
<li>jak nastavit společnou předponu v názvu klíče</li>
</ul>
<div style="text-align: justify;">
<br />
Nakonec jsem použil něco, co si pracovně nazývám <b><i>Fluent settings</i></b>. Pro výše uvedené požadavky jsem si definoval toto rozhraní:<br />
<br /></div>
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: darkblue;">IBindingRule</span><<span style="color: darkblue;">TElement</span>>
{
<span style="color: darkblue;">IBindingRule</span><<span style="color: darkblue;">TElement</span>> <span style="color: darkcyan;">Exclude</span><<span style="color: darkblue;">TProperty</span>>(<span style="color: darkblue;">Expression</span><<span style="color: darkblue;">Func</span><<span style="color: darkblue;">TElement</span>, <span style="color: darkblue;">TProperty</span>>> <span style="color: slategrey;">propertyLambda</span>);
<span style="color: darkblue;">IBindingRule</span><<span style="color: darkblue;">TElement</span>> <span style="color: darkcyan;">SetOnly</span><<span style="color: darkblue;">TProperty</span>>(<span style="color: darkblue;">Expression</span><<span style="color: darkblue;">Func</span><<span style="color: darkblue;">TElement</span>, <span style="color: darkblue;">TProperty</span>>> <span style="color: slategrey;">propertyLambda</span>);
<span style="color: darkblue;">IBindingRule</span><<span style="color: darkblue;">TElement</span>> <span style="color: darkcyan;">MapTo</span><<span style="color: darkblue;">TProperty</span>>(
<span style="color: darkblue;">Expression</span><<span style="color: darkblue;">Func</span><<span style="color: darkblue;">TElement</span>, <span style="color: darkblue;">TProperty</span>>> <span style="color: slategrey;">propertyLambda</span>,
<span style="color: blue;">string</span> <span style="color: slategrey;">sourceName</span>);
<span style="color: darkblue;">IBindingRule</span><<span style="color: darkblue;">TElement</span>> <span style="color: darkcyan;">Prefix</span>(<span style="color: blue;">string</span> <span style="color: slategrey;">name</span>);
<span style="color: darkblue;">IBindingRule</span><<span style="color: darkblue;">TElement</span>> <span style="color: darkcyan;">From</span>(<span style="color: darkblue;">IValueProvider</span> <span style="color: slategrey;">source</span>);
}</pre>
<div style="text-align: justify;">
<br />
a metodu pro vytvoření objektu a jeho naplnění konfiguračními daty jsem upravil takto:<br />
<br /></div>
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: blue;">public</span> <span style="color: blue;">delegate</span> <span style="color: blue;">void</span> <span style="color: darkblue;">ConfigurationBindingSettings</span><<span style="color: darkblue;">TElement</span>>(<span style="color: darkblue;">IBindingRule</span><<span style="color: darkblue;">TElement</span>> <span style="color: slategrey;">element</span>);
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: darkblue;">TElement</span> <span style="background: yellow; color: darkcyan;">CreateAndSetInstance</span><<span style="color: darkblue;">TElement</span>>(<span style="color: darkblue;">ConfigurationBindingSettings</span><<span style="color: darkblue;">TElement</span>> <span style="color: slategrey;">settings</span>)
</pre>
<div style="text-align: justify;">
<br />
Tato metoda si po spuštění vytvoří instanci objektu, který rozhraní implementuje a vykoná všechny určené akce (voláním <b>settings</b><i>(instance objektu)</i>). Ve výsledku to pak vše dohromady umožní tento zápis v kódu, který vytvoří instanci třídy <b>ConnectionPolicy</b> a naplní ji konfiguračními hodnotami mimo třech určených vlastnosti:</div>
<div style="text-align: justify;">
<br /></div>
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: blue;">var</span> documentDbConnectionPolicy = <span style="color: darkblue;">ConfigurationActivator</span>.<span style="background: yellow; color: darkcyan;">CreateAndSetInstance</span><<span style="color: darkblue;">ConnectionPolicy</span>>(
<span style="color: slategrey;">settings</span> => <span style="color: slategrey;">settings</span>
.<span style="color: darkcyan;">From</span>(<span style="color: darkblue;">From</span>.<span style="background: yellow; color: darkcyan;">ServiceFabricConfigurationPackage</span>(<span style="color: #a31515;">"Config"</span>, <span style="color: #a31515;">"Policy"</span>))
.<span style="color: darkcyan;">Prefix</span>(<span style="color: #a31515;">"DocumentDb.ConnectionPolicy"</span>)
.<span style="color: darkcyan;">Exclude</span>(<span style="color: slategrey;">p</span> => <span style="color: slategrey;">p</span>.<span style="color: purple;">EnableEndpointDiscovery</span>)
.<span style="color: darkcyan;">Exclude</span>(<span style="color: slategrey;">p</span> => <span style="color: slategrey;">p</span>.<span style="color: purple;">MaxConnectionLimit</span>)
.<span style="color: darkcyan;">Exclude</span>(<span style="color: slategrey;">p</span> => <span style="color: slategrey;">p</span>.<span style="color: purple;">UserAgentSuffix</span>));</pre>
<br />
Ten delegát je vlastně jen náhradou zápisu <b>Action<IBindingRule<TElement>></b>, který nemá CA rád.<br />
<div style="text-align: justify;">
Díky výše uvedenému způsobu není nutné definovat metodu <b>CreateAndSetInstance</b> několikrát s různými vstupními parametry.</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-88461003270971715692016-09-15T08:43:00.005+02:002016-09-15T08:43:56.137+02:00Pár tipů pro práci s Visual Studiem - Cops and Resources<div style="text-align: justify;">
Pokud píšete kód a používáte pro jeho kontrolu jak Code Analysis (aka FxCop), tak i StyleCop, tak vás jejich hlášky, samozřejmě v závislosti na zapnutých pravidlech, dokáží někdy dovést k šílenství, či alespoň k jeho okraji. Zejména pokud neprochází i vygenerovaný kód, a to i v případech, že se o něj postaraly knihovny a nástroje od firmy Microsoft.</div>
<br />
<a name='more'></a><br />
Naštěstí existují tyhle dvě finty, jak chybové hlášky potlačit:<br />
<br />
pro StyleCop: na začátek souboru je nutné přidat tento komentář:<br />
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;"><span style="color: green;">// <auto-generated></span>
</pre>
<br />
pro Code Analysis: odekorováním třídy atributem GeneratedCode, například:<br />
<br />
<pre style="background: white; color: black; font-family: "consolas"; font-size: 13;">[<span style="color: darkblue;">GeneratedCode</span>(<span style="color: #a31515;">"Tool"</span>, <span style="color: #a31515;">"version"</span>)]
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">class</span> <span style="color: darkblue;">Startup</span></pre>
<br />
Otravné hlášky, se kterými stejně nejde většinou nic dělat, zmizí.<br />
<h2>
Resources</h2>
<div style="text-align: justify;">
Někdy se překopíruje část kódu využívajícího resources do jiného projektu, resource soubor se pak překopíruje taky. Někdy ovšem obsahuje více položek, než které se v kopírovaném kódu skutečně používají a je tedy dobré je odstranit. Pomocí nástoje <b>ResXManager</b>, což je rozšíření pro Visual Studio a který je dostupný na adrese:<br /><a href="https://visualstudiogallery.msdn.microsoft.com/3b64e04c-e8de-4b97-8358-06c73a97cc68">https://visualstudiogallery.msdn.microsoft.com/3b64e04c-e8de-4b97-8358-06c73a97cc68</a><span style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px;"> </span><br />lze takové sirotky snadno vyhledat.</div>
<div style="text-align: justify;">
Pro správnou detekci je dobré dočasně vypnout ostatní projekty, které by mohly používat resource se stejným názvem (toho lze docílit pravým klikem na název projektu v <b>Solution Explorer</b> window a poté kliknutím na <b>Unload Project</b>). </div>
Nástroj lze navíc použít i pro jinou práci s resources soubory - jejich správu, export, překlad.mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-75897402834981020452016-08-09T23:33:00.002+02:002016-08-09T23:33:44.954+02:00Načtení objektu z konfiguračního souboru - 2<div style="text-align: justify;">
Nedávno jsem <a href="http://martinstrimpfl.blogspot.com/2016/06/nacteni-objektu-z-konfiguracniho-souboru.html">zde popsal způsob</a>, jak snadno načíst hodnoty z konfiguračního souboru do objektu v případě, že se použije appSettings a název klíče odpovídá názvu vlastnosti třídy. Někdy ale existuje požadavek vyjádřit konfiguraci více klasicky, tedy pomocí xml. I když :NET framework poskytuje způsob, jak xml z konfiguračního souboru převést na objekt, je tato možnost dle mého názoru krkolomná a lze to i jednodušeji.</div>
<a name='more'></a><br />
<div style="text-align: justify;">
Pokud máme v konfiguračním souboru tento zápis:</div>
<pre><code><span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">idnes</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">Uri</span><span class="XML Delimiter" style="color: blue;">></span><span class="XML Text">http://idnes.cz</span><span class="XML Delimiter" style="color: blue;"></</span><span class="XML Name" style="color: #a31515;">Uri</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">Name</span><span class="XML Delimiter" style="color: blue;">></span><span class="XML Text">idnes</span><span class="XML Delimiter" style="color: blue;"></</span><span class="XML Name" style="color: #a31515;">Name</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">RetryAttempts</span><span class="XML Delimiter" style="color: blue;">></span><span class="XML Text">5</span><span class="XML Delimiter" style="color: blue;"></</span><span class="XML Name" style="color: #a31515;">RetryAttempts</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">ConnectionPoint</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">Limit</span><span class="XML Delimiter" style="color: blue;">></span><span class="XML Text">10</span><span class="XML Delimiter" style="color: blue;"></</span><span class="XML Name" style="color: #a31515;">Limit</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">UseAlgorithm</span><span class="XML Delimiter" style="color: blue;">></span><span class="XML Text">true</span><span class="XML Delimiter" style="color: blue;"></</span><span class="XML Name" style="color: #a31515;">UseAlgorithm</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> </</span><span class="XML Name" style="color: #a31515;">ConnectionPoint</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> </</span><span class="XML Name" style="color: #a31515;">idnes</span><span class="XML Delimiter" style="color: blue;">></span></code></pre>
<div style="text-align: justify;">
Je jednou z možností vytvořit si nového potomka třídy <b>ConfigurationSection</b>, který tento zápis převede na "flat" podobu - tedy tak, aby bylo možné zpracování stejjným způsobme, jaký je popsán v předchozím článku. Takový potomek je překvapivě jednoduchý:</div>
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">GetNameValueSection</span> <span class="punctuation">:</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ConfigurationSection</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">private</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span><span class="punctuation">></span> <span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">getValue</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">null</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">protected</span> <span class="keyword" style="color: blue;">override</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">DeserializeSection</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">XmlReader</span> <span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">reader</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">nameValueDictionary</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Dictionary</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span><span class="punctuation">>();</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">List</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">></span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">path</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">List</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">>();</span>
<span class="keyword" style="color: blue;">while</span> <span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">reader</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">Read</span><span class="punctuation">())</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">switch</span> <span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">reader</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">NodeType</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">case</span> <span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">XmlNodeType</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.enum-field - (TRANSIENT)">Element</span><span class="punctuation">:</span>
<span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">path</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">Add</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">reader</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">Name</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">break</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">case</span> <span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">XmlNodeType</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.enum-field - (TRANSIENT)">EndElement</span><span class="punctuation">:</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">path</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">Count</span> <span class="operator">></span> <span class="number">0</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">path</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">RemoveAt</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">path</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">Count</span> <span class="operator">-</span> <span class="number">1</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">break</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">case</span> <span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">XmlNodeType</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.enum-field - (TRANSIENT)">Text</span><span class="punctuation">:</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">key</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">string</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">Join</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"."</span><span class="punctuation">,</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">path</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">ToArray</span><span class="punctuation">());</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">value</span> <span class="operator">=</span> <span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">reader</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">Value</span><span class="punctuation">;</span>
<span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">nameValueDictionary</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">Add</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">key</span><span class="punctuation">,</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">value</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">break</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">getValue</span> <span class="operator">=</span> <span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">name</span><span class="punctuation">)</span> <span class="operator">=></span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">nameValueDictionary</span><span class="punctuation">[</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">name</span><span class="punctuation">];</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">protected</span> <span class="keyword" style="color: blue;">override</span> <span class="keyword" style="color: blue;">object</span> <span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">GetRuntimeObject</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">getValue</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<div style="text-align: justify;">
Samozřejmě je nutné do konfiguračního souboru přidat sekci <b>configurationSection </b>a správně nastavit typ, který má být použit pro zpracování nově přidané sekce. V případě, že je třída <b>GetNameValueSection</b> umístněna v namespace <b>ConfigurationManagerHelper </b>v assembly <b>ConfigurationManagerHelper </b>bude použit tento zápis:<br />
<pre><code><span class="XML Delimiter" style="color: blue;"><?</span><span class="XML Name" style="color: #a31515;">xml</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">version</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">1.0</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">encoding</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">utf-8</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">?></span>
<span class="XML Delimiter" style="color: blue;"><</span><span class="XML Name" style="color: #a31515;">configuration</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">configSections</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">section</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">name</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">idnes</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">type</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">ConfigurationManagerHelper.GetNameValueSection, ConfigurationManagerHelper</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> /></span>
<span class="XML Delimiter" style="color: blue;"> </</span><span class="XML Name" style="color: #a31515;">configSections</span><span class="XML Delimiter" style="color: blue;">></span></code></pre>
A celé to lze použít takto snadno:</div>
<pre><code><span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">getValue</span> <span class="operator">=</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ConfigurationManager</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">GetSection</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"idnes"</span><span class="punctuation">)</span> <span class="keyword" style="color: blue;">as</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span><span class="punctuation">>;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">idnesConfiguration</span> <span class="operator">=</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">FlatConfigurationManager</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">CreateAndSetInstance</span><span class="punctuation"><</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">EndPoint</span><span class="punctuation">>(</span><span class="string" style="color: #a31515;">"idnes"</span><span class="punctuation">,</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">getValue</span><span class="punctuation">);</span></code></pre>
<div style="text-align: justify;">
Jistě by šlo použít <b>xmlReader </b>a provést prostou xml deserializaci, ale oproti xml deserializaci nemusí být cílová třída veřejná - tedy třída <b>EndPoint </b>použitá v příkladu může být privátní.<br />
<br />
Navíc, pokud raději napřed vytváříme konfigurační prezentaci a teprve pak třidu, můžeme postupovat takto:</div>
<div style="text-align: justify;">
1. Nejrpve do konfiguračního elementu zapíšeme data, například:</div>
<pre><code><span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">library</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">books</span><span class="XML Delimiter" style="color: blue;">></span><span class="XML Text">10</span><span class="XML Delimiter" style="color: blue;"></</span><span class="XML Name" style="color: #a31515;">books</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">magazines</span><span class="XML Delimiter" style="color: blue;">></span><span class="XML Text">34</span><span class="XML Delimiter" style="color: blue;"></</span><span class="XML Name" style="color: #a31515;">magazines</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> </</span><span class="XML Name" style="color: #a31515;">library</span><span class="XML Delimiter" style="color: blue;">></span></code></pre>
<div style="text-align: justify;">
2. Poté tento text označíme a zkopírujeme do schárnky.</div>
<div style="text-align: justify;">
3. Přejdeme do kódu a z nabídky Viual Studio <b>Edit </b>vybereme <b>Paste special </b>a následně možnost <b>Paste XML as classes</b>. Vygeneruje se tento kód:</div>
<pre><code><span class="xml doc comment - delimiter" style="color: grey; font-style: italic;">///</span><span class="xml doc comment - text" style="color: green; font-style: italic;"> </span><span class="xml doc comment - delimiter" style="color: grey; font-style: italic;"><</span><span class="xml doc comment - name" style="color: grey; font-style: italic;">remarks</span><span class="xml doc comment - delimiter" style="color: grey; font-style: italic;">/></span>
<span class="punctuation">[</span><span class="identifier - s.semantic-colorizer.namespace - unnecessary code - (TRANSIENT)" style="color: limegreen;">System</span><span class="operator - unnecessary code - (TRANSIENT)">.</span><span class="identifier - s.semantic-colorizer.namespace - unnecessary code - (TRANSIENT)" style="color: limegreen;">Xml</span><span class="operator - unnecessary code - (TRANSIENT)">.</span><span class="identifier - s.semantic-colorizer.namespace - unnecessary code - (TRANSIENT)" style="color: limegreen;">Serialization</span><span class="operator">.</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">XmlTypeAttribute</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">AnonymousType</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">true</span><span class="punctuation">)]</span>
<span class="punctuation">[</span><span class="identifier - s.semantic-colorizer.namespace - unnecessary code - (TRANSIENT)" style="color: limegreen;">System</span><span class="operator - unnecessary code - (TRANSIENT)">.</span><span class="identifier - s.semantic-colorizer.namespace - unnecessary code - (TRANSIENT)" style="color: limegreen;">Xml</span><span class="operator - unnecessary code - (TRANSIENT)">.</span><span class="identifier - s.semantic-colorizer.namespace - unnecessary code - (TRANSIENT)" style="color: limegreen;">Serialization</span><span class="operator">.</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">XmlRootAttribute</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">Namespace</span> <span class="operator">=</span> <span class="string" style="color: #a31515;">""</span><span class="punctuation">,</span> <span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">IsNullable</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">false</span><span class="punctuation">)]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">partial</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">library</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">byte</span> <span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">booksField</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">byte</span> <span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">magazinesField</span><span class="punctuation">;</span>
<span class="xml doc comment - delimiter" style="color: grey; font-style: italic;">///</span><span class="xml doc comment - text" style="color: green; font-style: italic;"> </span><span class="xml doc comment - delimiter" style="color: grey; font-style: italic;"><</span><span class="xml doc comment - name" style="color: grey; font-style: italic;">remarks</span><span class="xml doc comment - delimiter" style="color: grey; font-style: italic;">/></span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">byte</span> <span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">books</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">get</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">booksField</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">set</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">booksField</span> <span class="operator">=</span> <span class="identifier - keyword - (TRANSIENT)" style="color: blue;">value</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="xml doc comment - delimiter" style="color: grey; font-style: italic;">///</span><span class="xml doc comment - text" style="color: green; font-style: italic;"> </span><span class="xml doc comment - delimiter" style="color: grey; font-style: italic;"><</span><span class="xml doc comment - name" style="color: grey; font-style: italic;">remarks</span><span class="xml doc comment - delimiter" style="color: grey; font-style: italic;">/></span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">byte</span> <span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">magazines</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">get</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">magazinesField</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">set</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">magazinesField</span> <span class="operator">=</span> <span class="identifier - keyword - (TRANSIENT)" style="color: blue;">value</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<div style="text-align: justify;">
4. Z vygenerovaného kódu lze odstranit atributy a třídy změnit z public na private, tedy:</div>
<pre><code><span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">library</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">byte</span> <span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">booksField</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">byte</span> <span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">magazinesField</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">byte</span> <span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">books</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">get</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">booksField</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">set</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">booksField</span> <span class="operator">=</span> <span class="identifier - keyword - (TRANSIENT)" style="color: blue;">value</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">byte</span> <span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">magazines</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">get</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">magazinesField</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">set</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.field - (TRANSIENT)" style="color: navy;">magazinesField</span> <span class="operator">=</span> <span class="identifier - keyword - (TRANSIENT)" style="color: blue;">value</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<div style="text-align: justify;">
5. Do <b>configSection </b>v konfiguráku je nutné přidat správnou definici:<br />
<pre><code><span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">section</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">name</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">library</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">type</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">ConfigurationManagerHelper.GetNameValueSection, ConfigurationManagerHelper</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> /></span></code></pre>
6. A nyní je už možné získat v kódu objekt:<br />
<pre><code><span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">getValue</span> <span class="operator">=</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ConfigurationManager</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">GetSection</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"library"</span><span class="punctuation">)</span> <span class="keyword" style="color: blue;">as</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span><span class="punctuation">>;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">library</span> <span class="operator">=</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">FlatConfigurationManager</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">CreateAndSetInstance</span><span class="punctuation"><</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">library</span><span class="punctuation">>(</span><span class="string" style="color: #a31515;">"library"</span><span class="punctuation">,</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">getValue</span><span class="punctuation">);</span></code></pre>
</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com3tag:blogger.com,1999:blog-2993762679677061763.post-57613595664516691742016-07-31T16:24:00.004+02:002016-07-31T16:27:11.030+02:00Poznámky z code review - čekací smyčky<div style="text-align: justify;">
Někdy je potřeba provést operaci, která může déle trvat. Navíc v případě, že se tato operace provádí delší než maximálně očekávanou dobu, je pak obvykle nutné provést nějakou další operaci - například prodloužit "zámek" nad vzkazem ve frontě apod. Obvykle se tedy spustí čekací smyčka, která hlídá nepřekročení časového limitu a je zrušena po úspěšném provedení hlavní operace.</div>
<br />
<a name='more'></a><br />
Takovou delší operaci lze napodobit následujícím kódem:<br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">cancellationSource</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CancellationTokenSource</span><span class="punctuation">();</span>
<span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">WatchExeTime</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">InformAboutLongTime</span><span class="punctuation">,</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">cancellationSource</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">Token</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Console</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">WriteLine</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"Going to execute a long time operation."</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Thread</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">Sleep</span><span class="punctuation">(</span><span class="number">16000</span><span class="punctuation">);</span>
<span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">cancellationSource</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">Cancel</span><span class="punctuation">();</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Console</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">WriteLine</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"The long time operation executed"</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Console</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">ReadLine</span><span class="punctuation">();</span></code></pre>
<br />
<div style="text-align: justify;">
Samozřejmě, že v reálném kódu bude délka trvání operace proměnná, nastavil jsem zde napevno 16 sekund. Každé tři sekundy je přitom nutné informovat o běhu operace, to zde zastává metoda InformAboutLongTime, která jen na konzoli vypíše hlášení - opět, v reálném kódu by se volala jiná operace, například již zmíněné prodloužení zámku nad zprávou.</div>
<pre><code><span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">InformAboutLongTime</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Console</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">WriteLine</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"The operation in progress, please wait"</span><span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
Vlastní hlídací metoda pak byla realizována takto:<br />
<pre><code><span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">WatchExeTime</span><span class="punctuation">(</span><span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Action</span> <span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">action</span><span class="punctuation">,</span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">CancellationToken</span> <span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">cancellationToken</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Task</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">Run</span><span class="punctuation">(</span>
<span class="punctuation">()</span> <span class="operator">=></span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">sw</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Stopwatch</span><span class="punctuation">();</span>
<span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">sw</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">Start</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">invokeAt</span> <span class="operator">=</span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">FromSeconds</span><span class="punctuation">(</span><span class="number">3</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">while</span> <span class="punctuation">(</span><span class="keyword" style="color: blue;">true</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">cancellationToken</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">IsCancellationRequested</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">sw</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">Elapsed</span> <span class="operator">></span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">invokeAt</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">action</span><span class="punctuation">();</span>
<span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">sw</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">Restart</span><span class="punctuation">();</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="punctuation">},</span>
<span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">cancellationToken</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">ContinueWith</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">t</span> <span class="operator">=></span> <span class="punctuation">{</span> <span class="punctuation">},</span> <span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">TaskContinuationOptions</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.enum-field - (TRANSIENT)">OnlyOnFaulted</span><span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
<br />
<div style="text-align: justify;">
A co je na něm špatně? Kód ve smyčce se neustále opakuje, CPU je tak zbytečně vytížena. Pokud je tato aplikace, která vlastně nic nedělá, spuštěna, a pomocí Diagnostic Tools sledujete vytížení CPU, může tato aplikace vytížit CPU z nezanedbatelné části - bude se jednat o desítky procent:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn9uE9iVl10KEQv8mcSVzijb3_i7YBX096ZJUTs2y_eUuEDl_IVj_vuWBc55zv_k2cQolFJ2ABDVuRlhYE9q3mdEPxusA9Fyo5x1WrzBlYuKILUiGT-lErG6E2rrFv-oOR4hjDpfMG0x0/s1600/CpuBeforeLoop.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn9uE9iVl10KEQv8mcSVzijb3_i7YBX096ZJUTs2y_eUuEDl_IVj_vuWBc55zv_k2cQolFJ2ABDVuRlhYE9q3mdEPxusA9Fyo5x1WrzBlYuKILUiGT-lErG6E2rrFv-oOR4hjDpfMG0x0/s1600/CpuBeforeLoop.JPG" /></a></div>
<div style="text-align: justify;">
<br /></div>
Přitom stačí jen vhodně využít vlastnost <b>CancellationToken</b> a přepsat kód takto:<br />
<pre><code><span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">WatchExeTime</span><span class="punctuation">(</span><span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Action</span> <span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">action</span><span class="punctuation">,</span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">CancellationToken</span> <span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">cancellationToken</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Task</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">Run</span><span class="punctuation">(</span>
<span class="punctuation">()</span> <span class="operator">=></span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">waitFor</span> <span class="operator">=</span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.static-method - (TRANSIENT)" style="color: navy;">FromSeconds</span><span class="punctuation">(</span><span class="number">3</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">while</span> <span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">cancellationToken</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">IsCancellationRequested</span> <span class="operator">==</span> <span class="keyword" style="color: blue;">false</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">cancelled</span> <span class="operator">=</span> <span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">cancellationToken</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.property - (TRANSIENT)">WaitHandle</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">WaitOne</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">waitFor</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.local - (TRANSIENT)">cancelled</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">break</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">action</span><span class="punctuation">();</span>
<span class="punctuation">}</span>
<span class="punctuation">},</span>
<span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">cancellationToken</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.normal-method - (TRANSIENT)">ContinueWith</span><span class="punctuation">(</span><span class="identifier - s.semantic-colorizer.parameter - (TRANSIENT)" style="color: slategrey;">t</span> <span class="operator">=></span> <span class="punctuation">{</span> <span class="punctuation">},</span> <span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">TaskContinuationOptions</span><span class="operator">.</span><span class="identifier - s.semantic-colorizer.enum-field - (TRANSIENT)">OnlyOnFaulted</span><span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
<br />
<div style="text-align: justify;">
Mimo to, že je kód kratší a tedy přehlednější a udržovatelnější, klesne hlavně i vytížení CPU - a to velmi podstatně:<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju2wz9Ita1mH0UkS9IWabgfZfzm4Wgl7uLfNXypXPu9ciD2u7IbaC9RThkjCHjcc1R1nGi0Ksx5pQoJnp4rrULKq0gGV4CpzWKoXUcjZWmSdCMUsaarJ0hV93cEfMiN9dNOO1ZsaxZDvM/s1600/CpuAfterLoop.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju2wz9Ita1mH0UkS9IWabgfZfzm4Wgl7uLfNXypXPu9ciD2u7IbaC9RThkjCHjcc1R1nGi0Ksx5pQoJnp4rrULKq0gGV4CpzWKoXUcjZWmSdCMUsaarJ0hV93cEfMiN9dNOO1ZsaxZDvM/s1600/CpuAfterLoop.JPG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
Celý kód je dostupný zde a o vhodnosti tohoto přístupu se lze přesvědčit záměnou metod <b><span style="color: #cc0000;">WatchExeTime</span></b> (nevhodný přístup) a <b><span style="color: #6aa84f;">WatchExeTime2</span></b> (vhodný přístup) :</div>
<iframe frameborder="0" height="475" src="https://dotnetfiddle.net/Widget/rJkAZR" width="100%"></iframe>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com3tag:blogger.com,1999:blog-2993762679677061763.post-82389065451049480762016-06-20T06:40:00.000+02:002016-06-20T07:18:16.801+02:00Načtení objektu z konfiguračního souboru<div style="text-align: justify;">
V poslední době jsem narazil na pár projektů, kde jsou konfigurační hodnoty zapsány ve formátu, kterému pracovně říkám "flat". Programátor nepoužil některou z obvyklých technik, ale místo toho v <b>klíči</b> elementu v a<b>ppSettings</b> zachycuje částečně strukturu objektu a třídy a poté určuje její hodnotu v atributu <b>value</b>.</div>
<div style="text-align: justify;">
</div>
<a name='more'></a><br />
<br />
Například tomuto zápisu:<br />
<br />
<pre><code><span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">appSettings</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">add</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">key</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">idnes.Uri</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">value</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">http://idnes.cz</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">add</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">key</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">idnes.Name</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">value</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">idnes</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">add</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">key</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">idnes.RetryAttempts</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">value</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">5</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">add</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">key</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">idnes.ConnectionPoint.Limit</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">value</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">5</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">add</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">key</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">idnes.ConnectionPoint.UseAlgorithm</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">value</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">true</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> </</span><span class="XML Name" style="color: #a31515;">appSettings</span><span class="XML Delimiter" style="color: blue;">></span></code></pre>
<br />
odpovídají následující třídy:<br />
<br />
<pre><code><span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">EndPoint</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">string</span> <span class="identifier">Uri</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span><span class="punctuation">;</span> <span class="keyword" style="color: blue;">set</span><span class="punctuation">;</span> <span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">string</span> <span class="identifier">Name</span><span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span><span class="punctuation">;</span> <span class="keyword" style="color: blue;">set</span><span class="punctuation">;</span> <span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">RetryAttempts</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span><span class="punctuation">;</span> <span class="keyword" style="color: blue;">set</span><span class="punctuation">;</span> <span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ConnectionPoint</span> <span class="identifier">ConnectionPoint</span><span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span><span class="punctuation">;</span> <span class="keyword" style="color: blue;">set</span><span class="punctuation">;</span> <span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">ConnectionPoint</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">Limit</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span><span class="punctuation">;</span> <span class="keyword" style="color: blue;">set</span><span class="punctuation">;</span> <span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">bool</span> <span class="identifier">UseAlgorithm</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span><span class="punctuation">;</span> <span class="keyword" style="color: blue;">set</span><span class="punctuation">;</span> <span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<br />
Tyto třídy se v kódu vyplňují postupně, tedy asi nějak takto:<br />
<br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">endpoint</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">EndPoint</span><span class="punctuation">();</span>
<span class="identifier">endpoint</span><span class="operator">.</span><span class="identifier">Uri</span> <span class="operator">=</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ConfigurationManager</span><span class="operator">.</span><span class="identifier">AppSettings</span><span class="operator">.</span><span class="identifier">Get</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"idnes.Uri"</span><span class="punctuation">);</span>
<span class="identifier">endpoint</span><span class="operator">.</span><span class="identifier">RetryAttempts</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">int</span><span class="operator">.</span><span class="identifier">Parse</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ConfigurationManager</span><span class="operator">.</span><span class="identifier">AppSettings</span><span class="operator">.</span><span class="identifier">Get</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"idnes.RetryAttempts"</span><span class="punctuation">));</span></code></pre>
<br />
<div style="text-align: justify;">
a tak dále, co property, to řádek. Abych si ulehčil práci, napsal jsem si krátkou třídu, která umí podobné objekty sama naplnit. Má jen dvě metody a vypadá takto:</div>
<br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">FlatConfigurationManager</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span> <span class="identifier">CreateAndSetInstance</span><span class="punctuation"><</span><span class="type parameter name" style="color: #2b91af;">T</span><span class="punctuation">>(</span><span class="keyword" style="color: blue;">string</span> <span class="identifier">appSettingKeyName</span><span class="punctuation">,</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span><span class="punctuation">></span> <span class="identifier">getValues</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">instance</span> <span class="operator">=</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Activator</span><span class="operator">.</span><span class="identifier">CreateInstance</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">>();</span>
<span class="identifier">SetInstance</span><span class="punctuation">(</span><span class="identifier">instance</span><span class="punctuation">,</span> <span class="identifier">appSettingKeyName</span><span class="punctuation">,</span> <span class="identifier">getValues</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">instance</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">SetInstance</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">object</span> <span class="identifier">instance</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span> <span class="identifier">appSettingKeyName</span><span class="punctuation">,</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span><span class="punctuation">></span> <span class="identifier">getValues</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">properties</span> <span class="operator">=</span> <span class="identifier">instance</span><span class="operator">.</span><span class="identifier">GetType</span><span class="punctuation">()</span><span class="operator">.</span><span class="identifier">GetProperties</span><span class="punctuation">(</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">BindingFlags</span><span class="operator">.</span><span class="identifier">Public</span> <span class="operator">|</span> <span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">BindingFlags</span><span class="operator">.</span><span class="identifier">Instance</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">foreach</span> <span class="punctuation">(</span><span class="identifier - keyword - (TRANSIENT)" style="color: blue;">var</span> <span class="identifier">property</span> <span class="keyword" style="color: blue;">in</span> <span class="identifier">properties</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">keyName</span> <span class="operator">=</span> <span class="string" style="color: #a31515;">$"</span><span class="punctuation">{</span><span class="identifier">appSettingKeyName</span><span class="punctuation">}</span><span class="string" style="color: #a31515;">.</span><span class="punctuation">{</span><span class="identifier">property</span><span class="operator">.</span><span class="identifier">Name</span><span class="punctuation">}</span><span class="string" style="color: #a31515;">"</span><span class="punctuation">;</span>
<span class="identifier - keyword - (TRANSIENT)" style="color: blue;">dynamic</span> <span class="identifier">value</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier">property</span><span class="operator">.</span><span class="identifier">PropertyType</span><span class="operator">.</span><span class="identifier">IsClass</span> <span class="operator">&&</span> <span class="identifier">property</span><span class="operator">.</span><span class="identifier">PropertyType</span> <span class="operator">!=</span> <span class="keyword" style="color: blue;">typeof</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">))</span>
<span class="punctuation">{</span>
<span class="identifier">value</span> <span class="operator">=</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Activator</span><span class="operator">.</span><span class="identifier">CreateInstance</span><span class="punctuation">(</span><span class="identifier">property</span><span class="operator">.</span><span class="identifier">PropertyType</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">null</span><span class="punctuation">);</span>
<span class="identifier">SetInstance</span><span class="punctuation">(</span><span class="identifier">value</span><span class="punctuation">,</span> <span class="identifier">keyName</span><span class="punctuation">,</span> <span class="identifier">getValues</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">else</span>
<span class="identifier">value</span> <span class="operator">=</span> <span class="identifier">getValues</span><span class="punctuation">(</span><span class="identifier">keyName</span><span class="punctuation">);</span>
<span class="identifier">property</span><span class="operator">.</span><span class="identifier">SetValue</span><span class="punctuation">(</span><span class="identifier">instance</span><span class="punctuation">,</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Convert</span><span class="operator">.</span><span class="identifier">ChangeType</span><span class="punctuation">(</span><span class="identifier">value</span><span class="punctuation">,</span> <span class="identifier">property</span><span class="operator">.</span><span class="identifier">PropertyType</span><span class="punctuation">),</span> <span class="keyword" style="color: blue;">null</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<br />
Pro práci s ní pak stačí jen zavolat:<br />
<br />
<pre><code><span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">,</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">></span> <span class="identifier">getValue</span> <span class="operator">=</span> <span class="punctuation">(</span><span class="identifier">name</span><span class="punctuation">)</span> <span class="operator">=></span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ConfigurationManager</span><span class="operator">.</span><span class="identifier">AppSettings</span><span class="operator">.</span><span class="identifier">Get</span><span class="punctuation">(</span><span class="identifier">name</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">endpointIdnes</span> <span class="operator">=</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">FlatConfigurationManager</span><span class="operator">.</span><span class="identifier">CreateAndSetInstance</span><span class="punctuation"><</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">EndPoint</span><span class="punctuation">>(</span><span class="string" style="color: #a31515;">"idnes"</span><span class="punctuation">,</span> <span class="identifier">getValue</span><span class="punctuation">);</span></code></pre>
<br />
<div style="text-align: justify;">
Funkce se předává jednoduše proto, že "rodina" <b>ConfigurationManagerů </b>se nám rozrostla, mimo klasické třídy <b>ConfigurationManager </b> existuje třeba i <b>CloudConfigurationManager. </b>Takto se obejde nutnost definice společného interfejsu a wrapperů.</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-70676634747022513402016-06-15T21:41:00.000+02:002016-06-15T21:41:07.280+02:00Unit testy bez mockování<br />
<div style="text-align: justify;">
Při testování lze občas narazit na situace, kdy je napsání unit testů běžně zažitým způsobem nemožné a nejde použít ani mockování. Například proto, že v kódu je použita uzavřená (sealed) třída, která ani neimplementuje žádné rozhraní. To je například případ některých tříd pro přístup k datům na Azure, ale i mnoho dalších. I přesto se dá ale unit test napsat.</div>
<a name='more'></a><br />
<div style="text-align: justify;">
Pro ukázku jsem si zvolil velmi jednoduchou třídu s jedinou metodou, která umí vrátit jako text obsah souboru. Pokud dojde k IO výjimce, pokusí se metoda o čtení ještě x-krát a poté vrátí prázdný řetězec. Kód tedy vypadá nějak takto:</div>
<br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">FileReader</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">string</span> <span class="identifier">ReadContent</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">string</span> <span class="identifier">fileName</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">maxAttempts</span><span class="operator">=</span><span class="number">1</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">attempts</span> <span class="operator">=</span> <span class="number">0</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">do</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">try</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">File</span><span class="operator">.</span><span class="identifier">ReadAllText</span><span class="punctuation">(</span><span class="identifier">fileName</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">catch</span> <span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">IOException</span><span class="punctuation">)</span> <span class="keyword" style="color: blue;">when</span> <span class="punctuation">(</span><span class="identifier">attempts</span> <span class="operator"><</span> <span class="identifier">maxAttempts</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="identifier">attempts</span><span class="operator">++</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">catch</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">IOException</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">string</span><span class="operator">.</span><span class="identifier">Empty</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span> <span class="keyword" style="color: blue;">while</span> <span class="punctuation">(</span><span class="keyword" style="color: blue;">true</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<br />
<br />
<div style="text-align: justify;">
A jak k tomu napsat unit test? Těžko asi budeme nějak simulovat chybu na reálném souboru, stejně tak není ani řešením si třeba nadefinovat nějaké rozhraní s metodami dostupnými pro <b>File</b> a poté <b>File </b>obalit třídou implementující toto rozhraní. Respektive, bylo by to řešeni, ale třeba jsme líní a nechce se nám do toho, nebo je daná třída tak rozsáhlá, že by to vedlo k velkému zdržení.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I tak lze ale unit test napsat a to díky MS Fakes. Stačí jenom na příslušnou knihovnu, tedy tu co obsahuje nemokovatelnou třídu, kliknout v testovacím projektu pravým tlačítkem a vybrat <b>Add Fakes Assembly</b>.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4MmnYSnZ8_ewUbRQQJqzzKi02oJxlp49EP2XxvnD9M_M8dTMUgtXLYOchnpjNMtvYM7B_4AUZ9u-E8_RxWqekjnO0ajipXRW4nOhXW-0jZCAxqVvUNP2_eoeMY84X78yzP3zgl0XUEQc/s1600/Fakes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4MmnYSnZ8_ewUbRQQJqzzKi02oJxlp49EP2XxvnD9M_M8dTMUgtXLYOchnpjNMtvYM7B_4AUZ9u-E8_RxWqekjnO0ajipXRW4nOhXW-0jZCAxqVvUNP2_eoeMY84X78yzP3zgl0XUEQc/s320/Fakes.png" width="320" /></a></div>
<br />
A vygenerují se nám kopie, které můžeme nastavit jak potřebujeme a použít místo původních - a přidají se do seznamu <b><i>References</i></b> našeho testovacího projektu. Jejich použití je pak velmi snadné:</div>
<br />
<pre><code><span class="punctuation">[</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">TestMethod</span><span class="punctuation">()]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">ReadXTimesForIOExceptionAndReturnEmptyString</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">reader</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">FileReader</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">maxAttempts</span> <span class="operator">=</span> <span class="number">2</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">using</span> <span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ShimsContext</span><span class="operator">.</span><span class="identifier">Create</span><span class="punctuation">())</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">attempts</span> <span class="operator">=</span> <span class="number">0</span><span class="punctuation">;</span>
<span class="identifier">ShimFile</span><span class="operator">.</span><span class="identifier">ReadAllTextString</span> <span class="operator">=</span> <span class="punctuation">(</span><span class="identifier">fileName</span><span class="punctuation">)</span> <span class="operator">=></span>
<span class="punctuation">{</span>
<span class="identifier">attempts</span><span class="operator">++</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">throw</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">IOException</span><span class="punctuation">();</span>
<span class="punctuation">};</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">result</span> <span class="operator">=</span> <span class="identifier">reader</span><span class="operator">.</span><span class="identifier">ReadContent</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"myfile"</span><span class="punctuation">,</span> <span class="identifier">maxAttempts</span><span class="punctuation">);</span>
<span class="identifier">attempts</span><span class="operator">--</span><span class="punctuation">;</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">maxAttempts</span><span class="punctuation">,</span> <span class="identifier">attempts</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">result</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">string</span><span class="operator">.</span><span class="identifier">Empty</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<br />
<div style="text-align: justify;">
A je to - MS vygeneroval Shim třídy a vložil je do stejných namespaců, ty ovšem mají příponu <b><i>.Fakes</i></b>, tedy místo <b>System.IO</b> používáme namespace <b>System.IO.Fakes </b>a místo třídy <b>File </b>pak <b>ShimFile</b>. To, že se mají použít tyto fake třídy, deklarujeme pomocí <b><i>using(ShimContext.Create())</i></b> a poté jen upravím, co se má při volání té či oné metody vlastně stát.</div>
Ostatně lze si takto napsat více testů:<br />
<br />
<pre><code><span class="punctuation">[</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">TestMethod</span><span class="punctuation">()]</span>
<span class="punctuation">[</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ExpectedException</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">typeof</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">SecurityException</span><span class="punctuation">))]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">AnyExceptionThrowsException</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">reader</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">FileReader</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">using</span> <span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ShimsContext</span><span class="operator">.</span><span class="identifier">Create</span><span class="punctuation">())</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">attempts</span> <span class="operator">=</span> <span class="number">0</span><span class="punctuation">;</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ShimFile</span><span class="operator">.</span><span class="identifier">ReadAllTextString</span> <span class="operator">=</span> <span class="punctuation">(</span><span class="identifier">fileName</span><span class="punctuation">)</span> <span class="operator">=></span>
<span class="punctuation">{</span>
<span class="identifier">attempts</span><span class="operator">++</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">throw</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">SecurityException</span><span class="punctuation">();</span>
<span class="punctuation">};</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">result</span> <span class="operator">=</span> <span class="identifier">reader</span><span class="operator">.</span><span class="identifier">ReadContent</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"myfile"</span><span class="punctuation">,</span> <span class="number">20</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<br />
<div style="text-align: justify;">
A ještě jeden tip - výše uvedeným postupem se vytvoří kopie všeho, což je často zbytečné - v projektu se po kliknutí po kliknuti <b>Add Fake Assembly </b>vytvořila složka <b>Fakes</b> a v ní jsou konfigurační soubory, ty si lze zeditovat a říci, co se má udělat: </div>
<br />
<pre><code><span class="XML Delimiter" style="color: blue;"><</span><span class="XML Name" style="color: #a31515;">Fakes</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">xmlns</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">http://schemas.microsoft.com/fakes/2011/</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">Assembly</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">Name</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">mscorlib</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">Version</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">4.0.0.0</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">StubGeneration</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">Clear</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> </</span><span class="XML Name" style="color: #a31515;">StubGeneration</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">ShimGeneration</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">Clear</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> <</span><span class="XML Name" style="color: #a31515;">Add</span><span class="XML Delimiter" style="color: blue;"> </span><span class="XML Attribute" style="color: red;">FullName</span><span class="XML Delimiter" style="color: blue;">=</span><span class="XML Attribute Quotes">"</span><span class="XML Attribute Value" style="color: blue;">System.IO.File!</span><span class="XML Attribute Quotes">"</span><span class="XML Delimiter" style="color: blue;">/></span>
<span class="XML Delimiter" style="color: blue;"> </</span><span class="XML Name" style="color: #a31515;">ShimGeneration</span><span class="XML Delimiter" style="color: blue;">></span>
<span class="XML Delimiter" style="color: blue;"></</span><span class="XML Name" style="color: #a31515;">Fakes</span><span class="XML Delimiter" style="color: blue;">></span></code></pre>
<br />
Blíže je vše popsáno třeba tady:<br />
<a href="http://stackoverflow.com/questions/24733827/shims-warning-messages">http://stackoverflow.com/questions/24733827/shims-warning-messages </a><br />
a nebo tady<br />
<a href="https://msdn.microsoft.com/en-us/library/hh549175(v=vs.140).aspx">https://msdn.microsoft.com/en-us/library/hh549175(v=vs.140).aspx</a><br />
<br />
<br />mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com1tag:blogger.com,1999:blog-2993762679677061763.post-58579686611176982682016-04-11T07:41:00.000+02:002016-04-11T07:41:11.275+02:00Linq a pracovní pohovor<br />
<div style="text-align: justify;">
Zjišťovat znalosti Linqu u pracovního pohovoru může být obtížné - s Linqem se asi setkal každý C# programátor, ale vždy záleží, do jaké hloubky se s touto technologií seznámil a jestli je si vědom některých záludností - a to nemusí být až tak snadné zjistit. </div>
<a name='more'></a><br />
Nicméně stačí dát uchazeči pár příkladů a lze tak alespoň zjistit základní znalosti.<br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">numbers</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">List</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">></span> <span class="punctuation">{</span> <span class="number">1</span><span class="punctuation">,</span><span class="number">2</span><span class="punctuation">,</span><span class="number">4</span><span class="punctuation">,</span><span class="number">5</span><span class="punctuation">,</span><span class="number">6</span><span class="punctuation">};</span>
<span class="comment" style="color: green; font-style: italic;">//let's get all even numbers</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">evenNumbers</span> <span class="operator">=</span> <span class="identifier">numbers</span><span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">n</span> <span class="operator">=></span> <span class="identifier">n</span> <span class="operator">%</span> <span class="number">2</span> <span class="operator">==</span> <span class="number">0</span><span class="punctuation">);</span>
<span class="comment" style="color: green; font-style: italic;">//add another number to the list</span>
<span class="identifier">numbers</span><span class="operator">.</span><span class="identifier">Add</span><span class="punctuation">(</span><span class="number">8</span><span class="punctuation">);</span>
<span class="comment" style="color: green; font-style: italic;">//check if there has been a change in the even numbers</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier">numbers</span><span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">n</span> <span class="operator">=></span> <span class="identifier">n</span> <span class="operator">%</span> <span class="number">2</span> <span class="operator">==</span> <span class="number">0</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">Count</span><span class="punctuation">()</span> <span class="operator">!=</span> <span class="identifier">evenNumbers</span><span class="operator">.</span><span class="identifier">Count</span><span class="punctuation">())</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Console</span><span class="operator">.</span><span class="identifier">WriteLine</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"Collection changed"</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">else</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Console</span><span class="operator">.</span><span class="identifier">WriteLine</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"No change in collection"</span><span class="punctuation">);</span></code></pre>
<br />
<div style="text-align: justify;">
Samozřejmě, že se vypíše, že kolekce se nezměnila - což může v případě nedokonalé znalosti Linqu leckoho překvapit, vždyť jsme hned z počátku získali kolekci sudých čísel, poté jsme nějaké sudé číslo přidali a přesto kód to vyhodnotí, že k žádné změně nedošlo.</div>
<div style="text-align: justify;">
Zákeřnost se skrývá v podstatě Linqu - tam, kde si programátor snad myslel, že získává kolekci sudých čísel, došlo pouze k naprogramování kódu, který umí sudá čísla z kolekce získat. Projevila se tady vlastnost "deferred execution" většiny metod Linqu. V cheatsheetu pro Linq (ke stažení <a href="http://martinstrimpfl.blogspot.cz/2016/02/linq-cheat-sheet.html">zde</a>) jsou takové metody graficky odděleny od těch, co se provedou okamžitě. Podobný příklad dokáže u pohovoru odhalit, zda uchazeč zná tento základní rys Linqu.</div>
<div style="text-align: justify;">
Jinou obdobou téhož chování může být tento příklad - ten předpokládá, že se uchazečem pobavíme i o návratových hodnotách a lehce se tak dotkneme i návrhu rozhraní. Uchazeči je předložen takovýto kód:</div>
<pre><code><span class="keyword" style="color: blue;">internal</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">Program</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">Main</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">[]</span> <span class="identifier">args</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">INumberSource</span> <span class="identifier">numberSource</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">NumberSource</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">numbers</span> <span class="operator">=</span> <span class="identifier">numberSource</span><span class="operator">.</span><span class="identifier">GetNumbers</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">list</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">List</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">>(</span><span class="identifier">numbers</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier">list</span><span class="operator">.</span><span class="identifier">Sum</span><span class="punctuation">()</span> <span class="operator">!=</span> <span class="identifier">numbers</span><span class="operator">.</span><span class="identifier">Sum</span><span class="punctuation">())</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">throw</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Exception</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"Something went wrong"</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">internal</span> <span class="keyword" style="color: blue;">interface</span> <span class="interface name" style="color: #2b91af;">INumberSource</span>
<span class="punctuation">{</span>
<span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">IEnumerable</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">></span> <span class="identifier">GetNumbers</span><span class="punctuation">();</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">internal</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">NumberSource</span> <span class="punctuation">:</span> <span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">INumberSource</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">IEnumerable</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">></span> <span class="identifier">GetNumbers</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Enumerable</span><span class="operator">.</span><span class="identifier">Empty</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">>();</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<br />
<div style="text-align: justify;">
První otázkou bývá, zda je kód v pořádku a zda nemůže dojít k vyvolání výjimky. V předloženém kódu ne, ale je vhodné používat <b>IEnumerable </b>jako návratový typ? A pokud ano, jak se s tím v kódu následně vypořádat (přiznám se, že <b>IEnumerable</b> jako návratový typ také používám). A co se stane, pokud se metoda změní takto:</div>
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">IEnumerable</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">></span> <span class="identifier">GetNumbers</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Random</span> <span class="identifier">rnd</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Random</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">return</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Enumerable</span><span class="operator">.</span><span class="identifier">Range</span><span class="punctuation">(</span><span class="number">1</span><span class="punctuation">,</span> <span class="number">10</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">i</span> <span class="operator">=></span> <span class="identifier">rnd</span><span class="operator">.</span><span class="identifier">Next</span><span class="punctuation">(</span><span class="number">0</span><span class="punctuation">,</span> <span class="number">10</span><span class="punctuation">));</span>
<span class="punctuation">}</span></code></pre>
<br />
<div style="text-align: justify;">
S největší pravděpodobností dojde k vyvolání výjimky. A jak tomu zabránit? Jednou z možností je nepoužívat <b>IEnumerable</b> jako návratový typ, takže při přepsání na pole už bude vše v pořádku:</div>
<pre><code><span class="keyword" style="color: blue;">internal</span> <span class="keyword" style="color: blue;">interface</span> <span class="interface name" style="color: #2b91af;">INumberSource</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">int</span><span class="punctuation">[]</span> <span class="identifier">GetNumbers</span><span class="punctuation">();</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">internal</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">NumberSource</span> <span class="punctuation">:</span> <span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">INumberSource</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">int</span><span class="punctuation">[]</span> <span class="identifier">GetNumbers</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Random</span> <span class="identifier">rnd</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Random</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">return</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Enumerable</span><span class="operator">.</span><span class="identifier">Range</span><span class="punctuation">(</span><span class="number">1</span><span class="punctuation">,</span> <span class="number">10</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">i</span> <span class="operator">=></span> <span class="identifier">rnd</span><span class="operator">.</span><span class="identifier">Next</span><span class="punctuation">(</span><span class="number">0</span><span class="punctuation">,</span> <span class="number">10</span><span class="punctuation">))</span><span class="operator">.</span><span class="identifier">ToArray</span><span class="punctuation">();</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Ne vždy je to ale vhodné a chceme pracovat s pevnou kolekcí - takový přístup, tedy mít "pevnou" kolekci je více než vhodný při předávání výsledku mezi vrstvami aplikace (sám jsem kdysi řešil problém vzniklý předáním <b>IEnumerable</b> jako výsledku akce <b><i>Controller</i></b>u v <b>ASP.NET MVC</b> :-) ), ale někdy se nám zase hodit nemusí a chceme mít skutečně návratový typ <b>IEnumerable</b>. V tom případě je odpovědnost na volajícím, který musí s podobným chováním počítat a vypořádat se s ním, třeba tím, že si "pevnou" kolekci hned vytvoří, například voláním <b>ToArray()</b>:</div>
<pre><code><span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">Main</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">[]</span> <span class="identifier">args</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">INumberSource</span> <span class="identifier">numberSource</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">NumberSource</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">numbers</span> <span class="operator">=</span> <span class="identifier">numberSource</span><span class="operator">.</span><span class="identifier">GetNumbers</span><span class="punctuation">()</span><span class="operator">.</span><span class="identifier">ToArray</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">list</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">List</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">>(</span><span class="identifier">numbers</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">if</span> <span class="punctuation">(</span><span class="identifier">list</span><span class="operator">.</span><span class="identifier">Sum</span><span class="punctuation">()</span> <span class="operator">!=</span> <span class="identifier">numbers</span><span class="operator">.</span><span class="identifier">Sum</span><span class="punctuation">())</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">throw</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Exception</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">"Something went wrong, "</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<br />
<div style="text-align: justify;">
Jak je tedy vidět, Linq může programátora někdy docela potrápit a být tak i vhodným tématem u pracovního pohovoru.</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-72055621305366005422016-04-08T07:07:00.000+02:002016-04-08T09:07:38.983+02:00Linq - k čemu použít Aggregate<div style="text-align: justify;">
K jednomu z předchozích článků, ve kterém jsem dal k dispozici <a href="http://martinstrimpfl.blogspot.cz/2016/02/linq-cheat-sheet.html">cheatsheet pro Linq</a>, se mne jeden známý zeptal, k čemu že je dobrý <b>Aggregate</b> - vždy si zatím vystačil například se <b>Sum</b>, <b>Count</b> či <b>Average</b>.</div>
<br />
<div style="text-align: justify;">
Nejlépe se vysvětluje na příkladě a zabrousím do oblasti hudebních alb: máme řetězec obsahující seznam délek jednotlivých skladeb a chceme získate celkový čas alba. </div>
<a name='more'></a><br />
Úkol jak stvořený pro Linq.
<br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">trackTimes</span> <span class="operator">=</span> <span class="string" style="color: #a31515;">"1:20,5:40,6:20, 10:40"</span><span class="punctuation">;</span></code></pre>
<!-- END -->
<br />
Nejprve si z řetězce uděláme kolekci jednotlivých délek, k tomu poslouží <b>Split</b>:
<!-- START --><br />
<pre><code><span class="operator">.</span><span class="identifier">Split</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">','</span><span class="punctuation">)</span></code></pre>
<!-- END -->
Nyní jednotlivé prvky převedeme na datový typ <b>TimeSpan</b>:<br />
<pre><code><span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">i</span> <span class="operator">=></span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span><span class="operator">.</span><span class="identifier">ParseExact</span><span class="punctuation">(</span><span class="identifier">i</span><span class="operator">.</span><span class="identifier">Trim</span><span class="punctuation">(),</span> <span class="string - verbatim" style="color: maroon;">@"m\:s"</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">null</span><span class="punctuation">))</span></code></pre>
<!-- END -->
A nyní nám to zbývá jen sečíst. Nabízí se<b> Sum</b>, ale ejhle, funguje jen pro číselné datové typy. Ale na vše ostatní je zde právě <b>Aggregate</b> a tak stačí napsat:
<!-- START --><br />
<pre><code><span class="operator">.</span><span class="identifier">Aggregate</span><span class="punctuation">(</span><span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span><span class="operator">.</span><span class="identifier">Zero</span><span class="punctuation">,</span> <span class="punctuation">(</span><span class="identifier">t1</span><span class="punctuation">,</span> <span class="identifier">t2</span><span class="punctuation">)</span> <span class="operator">=></span> <span class="identifier">t1</span> <span class="operator">+</span> <span class="identifier">t2</span><span class="punctuation">);</span></code></pre>
<!-- END --><b><i>
TimeSpan.Zero</i></b> není nutné použít, je to jen náznak, jak si můžeme něco přičíst k výsledné hodnotě hned na začátku (tady tedy nulu :-). Výsledný kód pak vypadá takto:<br />
<!-- START --><br />
<pre><code><span class="keyword - unnecessary code - (TRANSIENT)" style="color: blue;">internal</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">Program</span>
<span class="punctuation">{</span>
<span class="keyword - unnecessary code - (TRANSIENT)" style="color: blue;">private</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">Main</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">[]</span> <span class="identifier">args</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">trackTimes</span> <span class="operator">=</span> <span class="string" style="color: #a31515;">"1:20,5:40, 6:20"</span><span class="punctuation">;</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Console</span><span class="operator">.</span><span class="identifier">WriteLine</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">$"Total time is </span><span class="punctuation">{</span><span class="identifier">GetTotalTime</span><span class="punctuation">(</span><span class="identifier">trackTimes</span><span class="punctuation">)}</span><span class="string" style="color: #a31515;">."</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="keyword - unnecessary code - (TRANSIENT)" style="color: blue;">private</span> <span class="keyword" style="color: blue;">static</span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span> <span class="identifier">GetTotalTime</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">string</span> <span class="identifier">trackTimes</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">trackTimes</span>
<span class="operator">.</span><span class="identifier">Split</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">','</span><span class="punctuation">)</span>
<span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">i</span> <span class="operator">=></span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span><span class="operator">.</span><span class="identifier">ParseExact</span><span class="punctuation">(</span><span class="identifier">i</span><span class="operator">.</span><span class="identifier">Trim</span><span class="punctuation">(),</span> <span class="string - verbatim" style="color: maroon;">@"m\:s"</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">null</span><span class="punctuation">))</span>
<span class="operator">.</span><span class="identifier">Aggregate</span><span class="punctuation">(</span><span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span><span class="operator">.</span><span class="identifier">Zero</span><span class="punctuation">,</span> <span class="punctuation">(</span><span class="identifier">t1</span><span class="punctuation">,</span> <span class="identifier">t2</span><span class="punctuation">)</span> <span class="operator">=></span> <span class="identifier">t1</span> <span class="operator">+</span> <span class="identifier">t2</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
Samozřejmě lze kód napsat i s použitím <b>Sum</b>:
<!-- START --><br />
<pre><code><span class="keyword - unnecessary code - (TRANSIENT)" style="color: blue;">private</span> <span class="keyword" style="color: blue;">static</span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span> <span class="identifier">GetTotalTime</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">string</span> <span class="identifier">trackTimes</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span>
<span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span><span class="operator">.</span><span class="identifier">FromSeconds</span><span class="punctuation">(</span>
<span class="identifier">trackTimes</span>
<span class="operator">.</span><span class="identifier">Split</span><span class="punctuation">(</span><span class="string" style="color: #a31515;">','</span><span class="punctuation">)</span>
<span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">i</span> <span class="operator">=></span> <span class="identifier - struct name - (TRANSIENT)" style="color: #2b91af;">TimeSpan</span><span class="operator">.</span><span class="identifier">ParseExact</span><span class="punctuation">(</span><span class="identifier">i</span><span class="operator">.</span><span class="identifier">Trim</span><span class="punctuation">(),</span> <span class="string - verbatim" style="color: maroon;">@"m\:s"</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">null</span><span class="punctuation">))</span>
<span class="operator">.</span><span class="identifier">Sum</span><span class="punctuation">(</span><span class="identifier">t</span> <span class="operator">=></span> <span class="identifier">t</span><span class="operator">.</span><span class="identifier">TotalSeconds</span><span class="punctuation">)</span>
<span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-67499881595321497092016-03-16T07:49:00.000+01:002016-03-16T08:54:04.685+01:00Příklad na pohovor s programátorem - hotovost v pokladně<div style="text-align: justify;">
Na blogu jsem uveřejnil několik příkladů z pohovorů s uchazeči o místo programátora. Dovolím si tedy uveřejnit jeden z dalších možných příkladů, se kterým se lze setkat - na předešlé příspěvky jsem dostal emailem poměrně dost reakcí a překvapilo mne, že poměrně hodně lidí považuje příklady za jednoduché. Těžko to soudit, ale z mých několikaletých zkušeností ze zadávání podobných úkolů zvládne zadání implentovat méně než třetina kandidátů - a zcela uspokojivých jsou pak tak jedno až dvě řešení z deseti. Ono v poklidu u pracovního stolu vše vypadá jinak.<br />
<br />
<a name='more'></a><br />
<br />
Nejsem příznivcem zadávání "domácích" ukolů a tak se spíše spoléhám na to, co se ukáže při pohovoru a snažím se sledovat reakce a chování programátora. Ale někdo jiný může mít na tohle jiný názor.<br />
<br />
Takže zpět k příkladu - úkolem je navrhnout třídu či třídy, které by sloužily k sledování hotovosti na pokladně - tedy kolik bankovek a mincí v pokladně máme. Třída by měla umožňovat příjem a výdej hotovosti.<br />
<br />
<h3>
První kroky</h3>
Zadání je velmi obecné a očekává se, že se bude upřesňovat na základě otázek. Pokud se tedy uchazeč "chytne". Obvykle pak následuje první pokus řešení - použíje se instance třídy <b>Dictionary</b>, klíčem je typ bankovky či mice, hodnotou pak jejich počet. Takže nejprve se napíše výčet všech možných platidel (než se začne psát, je dobré si tedy napřed vyjasnit, pro jakou měnu kód píšeme):
<!-- START --></div>
<br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">enum</span> <span class="enum name" style="color: #2b91af;">CzechMoney</span>
<span class="punctuation">{</span>
<span class="identifier">Kc1</span><span class="operator">=</span> <span class="number">1</span><span class="punctuation">,</span>
<span class="identifier">Kc2</span> <span class="operator">=</span> <span class="number">2</span><span class="punctuation">,</span>
<span class="identifier">Kc5</span> <span class="operator">=</span> <span class="number">3</span><span class="punctuation">,</span>
<span class="identifier">Kc10</span> <span class="operator">=</span> <span class="number">4</span><span class="punctuation">,</span>
<span class="identifier">Kc20</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">,</span>
<span class="identifier">Kc50</span> <span class="operator">=</span> <span class="number">6</span><span class="punctuation">,</span>
<span class="identifier">Kc100</span> <span class="operator">=</span> <span class="number">7</span><span class="punctuation">,</span>
<span class="identifier">Kc200</span> <span class="operator">=</span> <span class="number">8</span><span class="punctuation">,</span>
<span class="identifier">Kc500</span> <span class="operator">=</span> <span class="number">9</span><span class="punctuation">,</span>
<span class="identifier">Kc1000</span> <span class="operator">=</span> <span class="number">10</span><span class="punctuation">,</span>
<span class="identifier">Kc2000</span> <span class="operator">=</span> <span class="number">11</span><span class="punctuation">,</span>
<span class="identifier">Kc5000</span> <span class="operator">=</span> <span class="number">12</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
a stav "pokladny" lze držet v instanci <b>Dictionary</b>:<br />
<!-- START -->
<br />
<pre><code><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Dictionary</span><span class="punctuation"><</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">int</span><span class="punctuation">></span> <span class="identifier">cash</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Dictionary</span><span class="punctuation"><</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">int</span><span class="punctuation">>();</span></code></pre>
<!-- END -->
<br />
<div style="text-align: justify;">
S takovýmto základem následuje obyčejně napsání vlastní třídy, která umožní <i>bezpečnější</i> práci. Mimochodem se tak i ukáže, zda se programátor někdy setkal s indexery. Při psaní takové třídy je obvykle dobrým znamením, pokud si programátor ujasňuje se zadavatelem vyžadované chování - například co se má stát, pokud se pokusíme zadat zápornou hodnotu - zda to má kód vůbec umožnit a tedy zda by místo datového typu <b>int </b>nebylo lepší použít typ <b>uint</b> a podobně.</div>
<div style="text-align: justify;">
<h3>
</h3>
<h3>
Převedení do třídy</h3>
Do poklady bychom také chtěli přidávat a nebo z ní vybírat hotovost - což je opět příležitost pro kladní otázek, například jak by se měla třída zachovat při pokusu vybrat z ní více, než v ní je - je možné takový stav potichu ignorovat, vyvolat vyjímku a nebo implementovat metody <b><i>TryRemove</i></b> apod.</div>
<pre><code><span class="keyword" style="color:blue;">public</span> <span class="keyword" style="color:blue;">class</span> <span class="class name" style="color:#2b91af;">CzechCash</span><br/><span class="punctuation">{</span><br/> <span class="keyword" style="color:blue;">private</span> <span class="keyword" style="color:blue;">readonly</span> <span class="class name - identifier - (TRANSIENT)" style="color:#2b91af;">Dictionary</span><span class="punctuation"><</span><span class="enum name - identifier - (TRANSIENT)" style="color:#2b91af;">CzechMoney</span><span class="punctuation">,</span> <span class="keyword" style="color:blue;">uint</span><span class="punctuation">></span> <span class="identifier">cash</span> <span class="operator">=</span> <span class="keyword" style="color:blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color:#2b91af;">Dictionary</span><span class="punctuation"><</span><span class="enum name - identifier - (TRANSIENT)" style="color:#2b91af;">CzechMoney</span><span class="punctuation">,</span> <span class="keyword" style="color:blue;">uint</span><span class="punctuation">>();</span><br/> <br/> <span class="keyword" style="color:blue;">public</span> <span class="keyword" style="color:blue;">uint</span> <span class="keyword" style="color:blue;">this</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color:#2b91af;">CzechMoney</span> <span class="identifier">what</span><span class="punctuation">]</span><br/> <span class="punctuation">{</span><br/> <span class="keyword" style="color:blue;">get</span><br/> <span class="punctuation">{</span><br/> <span class="keyword" style="color:blue;">if</span> <span class="punctuation">(</span><span class="keyword" style="color:blue;">this</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">ContainsKey</span><span class="punctuation">(</span><span class="identifier">what</span><span class="punctuation">))</span><br/> <span class="keyword" style="color:blue;">return</span> <span class="keyword" style="color:blue;">this</span><span class="operator">.</span><span class="identifier">cash</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">];</span><br/> <br/> <span class="keyword" style="color:blue;">return</span> <span class="number">0</span><span class="punctuation">;</span><br/> <span class="punctuation">}</span><br/> <br/> <span class="keyword" style="color:blue;">set</span><br/> <span class="punctuation">{</span><br/> <span class="keyword" style="color:blue;">if</span> <span class="punctuation">(</span><span class="operator">!</span><span class="keyword" style="color:blue;">this</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">ContainsKey</span><span class="punctuation">(</span><span class="identifier">what</span><span class="punctuation">))</span><br/> <span class="keyword" style="color:blue;">this</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Add</span><span class="punctuation">(</span><span class="identifier">what</span><span class="punctuation">,</span> <span class="identifier - keyword - (TRANSIENT)" style="color:blue;">value</span><span class="punctuation">);</span><br/> <span class="keyword" style="color:blue;">else</span><br/> <span class="keyword" style="color:blue;">this</span><span class="operator">.</span><span class="identifier">cash</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="identifier - keyword - (TRANSIENT)" style="color:blue;">value</span><span class="punctuation">;</span><br/> <span class="punctuation">}</span><br/> <span class="punctuation">}</span><br/> <br/> <span class="keyword" style="color:blue;">public</span> <span class="keyword" style="color:blue;">void</span> <span class="identifier">Add</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color:#2b91af;">CzechCash</span> <span class="identifier">anotherCash</span><span class="punctuation">)</span><br/> <span class="punctuation">{</span><br/> <span class="keyword" style="color:blue;">foreach</span> <span class="punctuation">(</span><span class="identifier - keyword - (TRANSIENT)" style="color:blue;">var</span> <span class="identifier">what</span> <span class="keyword" style="color:blue;">in</span> <span class="identifier">anotherCash</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Keys</span><span class="punctuation">)</span><br/> <span class="punctuation">{</span><br/> <span class="keyword" style="color:blue;">this</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">+=</span> <span class="identifier">anotherCash</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">];</span><br/> <span class="punctuation">}</span><br/> <span class="punctuation">}</span><br/> <br/> <span class="keyword" style="color:blue;">public</span> <span class="keyword" style="color:blue;">void</span> <span class="identifier">Remove</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color:#2b91af;">CzechCash</span> <span class="identifier">anotherCash</span><span class="punctuation">)</span><br/> <span class="punctuation">{</span><br/> <span class="keyword" style="color:blue;">foreach</span> <span class="punctuation">(</span><span class="identifier - keyword - (TRANSIENT)" style="color:blue;">var</span> <span class="identifier">what</span> <span class="keyword" style="color:blue;">in</span> <span class="identifier">anotherCash</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Keys</span><span class="punctuation">)</span><br/> <span class="punctuation">{</span><br/> <span class="keyword" style="color:blue;">this</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">-=</span> <span class="identifier">anotherCash</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">];</span><br/> <span class="punctuation">}</span><br/> <span class="punctuation">}</span><br/><span class="punctuation">}</span></code></pre>
<br />
<h3>
Testování</h3>
<div style="text-align: justify;">
V tomhle bodě je už dobré, aby se doplnily i testy. Někdo to začně dělat sám od sebe, někdy si napíše jednoduchý kód pro otestování v hlavním kódu (metoda <b>Main</b>) a třeba později jej přesune do unit testových tříd, občas zůstane jen u toho - lze z toho usoudit na pokročilost programátora.<br />
<br /></div>
<div style="text-align: justify;">
Pokud programátor zapíše pro otestování jen spustitelný kód a spokojí se s tím, že mu projde, není to dobré znamení. Například podobný kód neodhalí závažnou chybu, která v kódu je:</div>
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">Program</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">Main</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">[]</span> <span class="identifier">args</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash1</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">4</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash2</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash2</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">8</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="operator">.</span><span class="identifier">Remove</span><span class="punctuation">(</span><span class="identifier">cash2</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
<br />
<div style="text-align: justify;">
Tenhle kód bez chyby proběhne a může vyvolat mylný dojem, že vše je v pořádku. I proto je lepší spoléhat na unit testy, testování pomocí nich může pro třídu <b><i>CzechCash</i></b> probíhat takto (je použit <b>MSTest </b>framework, v jiných by zápis vypadal samozřejmě jinak) :</div>
<!-- START --><br />
<pre><code><span class="punctuation">[</span><span class="class name - identifier - unnecessary code - (TRANSIENT)" style="color: #2b91af;">TestClass</span><span class="punctuation - unnecessary code - (TRANSIENT)">()</span><span class="punctuation">]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">CzechCashTests</span>
<span class="punctuation">{</span>
<span class="punctuation">[</span><span class="class name - identifier - unnecessary code - (TRANSIENT)" style="color: #2b91af;">TestMethod</span><span class="punctuation - unnecessary code - (TRANSIENT)">()</span><span class="punctuation">]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">AddTest</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash1</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">4</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash2</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash2</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">8</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="operator">.</span><span class="identifier">Add</span><span class="punctuation">(</span><span class="identifier">cash2</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">],</span> <span class="number">13U</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">],</span> <span class="number">4U</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">[</span><span class="class name - identifier - unnecessary code - (TRANSIENT)" style="color: #2b91af;">TestMethod</span><span class="punctuation - unnecessary code - (TRANSIENT)">()</span><span class="punctuation">]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">RemoveTest</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash1</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">4</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash2</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash2</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">8</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="operator">.</span><span class="identifier">Remove</span><span class="punctuation">(</span><span class="identifier">cash2</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">],</span> <span class="number">0U</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">],</span> <span class="number">4U</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
<br />
<div style="text-align: justify;">
Obvykle programátor zapíše tyhle testy bez <b>U</b> u číselných hodnot, na tuto chybu po spuštění testu poměrně rychle přijde.</div>
<br />
<h3>
Ošetření nalezených chyb</h3>
<div style="text-align: justify;">
Následně ale po spuštění takového testu rychle přijde i na to, že použití datového typu <b>uint</b> není zcela bez následku a vedlejších efektů - pokud odečteme více hotovosti, než máme, tak získáme "v pokladně" více peněz - právě k tomu jsou dobré unit testy, aby odhalily podobné chyby. Kód tak stačí upravit a dojde tak k vyhození vyjímky při přetečení rozsahu typu <b>uint</b>:</div>
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">Remove</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span> <span class="identifier">anotherCash</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">foreach</span> <span class="punctuation">(</span><span class="identifier - keyword - (TRANSIENT)" style="color: blue;">var</span> <span class="identifier">what</span> <span class="keyword" style="color: blue;">in</span> <span class="identifier">anotherCash</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Keys</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">this</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">checked</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">this</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">-</span> <span class="identifier">anotherCash</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]);</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
Samozřejmě je nutné i upravit testovací metodu, aby vyjímku považovala za správné chování:<br />
<!-- START --><br />
<pre><code><span class="punctuation">[</span><span class="class name - identifier - unnecessary code - (TRANSIENT)" style="color: #2b91af;">TestMethod</span><span class="punctuation - unnecessary code - (TRANSIENT)">()</span><span class="punctuation">]</span>
<span class="punctuation">[</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ExpectedException</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">typeof</span><span class="punctuation">(</span><span class="identifier - unnecessary code - (TRANSIENT)">System</span><span class="operator">.</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">OverflowException</span><span class="punctuation">))]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">RemoveTest</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash1</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">4</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash2</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash2</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">8</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="operator">.</span><span class="identifier">Remove</span><span class="punctuation">(</span><span class="identifier">cash2</span><span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
<br />
Vhodné je taktéž přidat další testování, například metodu:<br />
<!-- START --><br />
<pre><code><span class="punctuation">[</span><span class="class name - identifier - unnecessary code - (TRANSIENT)" style="color: #2b91af;">TestMethod</span><span class="punctuation - unnecessary code - (TRANSIENT)">()</span><span class="punctuation">]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">RemoveTest2</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash1</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">4</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash2</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash2</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">3</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="operator">.</span><span class="identifier">Remove</span><span class="punctuation">(</span><span class="identifier">cash2</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">],</span> <span class="number">2U</span><span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
<br />
<div style="text-align: justify;">
Jak si lze všimnout, tak pro pojmenování testovacích metod nepoužívám příliš výstížné názvy. Vhodné by bylo použít nějaký pojmenovávací vzor, například RemoveCash_ThrowException_WithdrawToMinus - shrnutí vhodných konvencí pro pojmenování lze nalézt například na <a href="https://dzone.com/articles/7-popular-unit-test-naming">https://dzone.com/articles/7-popular-unit-test-naming</a></div>
<br />
<h3>
Podpora sčítání a odečítání</h3>
<!-- END -->
Dalším požadavkem je podpora základních aritmetických operací, chtěli bychom dvě hotovosti sčítat či odečítat, tady mít možnost napsat takovýto kód: var cash = cash1 + cash2;<br />
<br />
Zde se ukáže, zda programátor tuší, že lze toto implementovat a jak toho dosáhnout:<br />
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span> <span class="keyword" style="color: blue;">operator</span> <span class="operator">+</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span> <span class="identifier">mc1</span><span class="punctuation">,</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span> <span class="identifier">mc2</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">result</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">whats</span> <span class="operator">=</span> <span class="identifier">mc1</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Keys</span><span class="operator">.</span><span class="identifier">Union</span><span class="punctuation">(</span><span class="identifier">mc2</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Keys</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">foreach</span> <span class="punctuation">(</span><span class="identifier - keyword - (TRANSIENT)" style="color: blue;">var</span> <span class="identifier">what</span> <span class="keyword" style="color: blue;">in</span> <span class="identifier">whats</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="identifier">result</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="identifier">mc1</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">+</span> <span class="identifier">mc2</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">];</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">result</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span> <span class="keyword" style="color: blue;">operator</span> <span class="operator">-</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span> <span class="identifier">mc1</span><span class="punctuation">,</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span> <span class="identifier">mc2</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">result</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">whats</span> <span class="operator">=</span> <span class="identifier">mc1</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Keys</span><span class="operator">.</span><span class="identifier">Union</span><span class="punctuation">(</span><span class="identifier">mc2</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Keys</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">foreach</span> <span class="punctuation">(</span><span class="identifier - keyword - (TRANSIENT)" style="color: blue;">var</span> <span class="identifier">what</span> <span class="keyword" style="color: blue;">in</span> <span class="identifier">whats</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="identifier">result</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">checked</span><span class="punctuation">(</span><span class="identifier">mc1</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]</span> <span class="operator">-</span> <span class="identifier">mc2</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">]);</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">result</span><span class="punctuation">;</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
<br />
<div style="text-align: justify;">
<br />
Opět by měly být doplněny testy, tedy například tento kód:<br />
<!-- START --><br />
<pre><code><span class="punctuation">[</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">TestMethod</span><span class="punctuation">]</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">AddCash</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash1</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">4</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash2</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash2</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">3</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash</span> <span class="operator">=</span> <span class="identifier">cash1</span> <span class="operator">+</span> <span class="identifier">cash2</span><span class="punctuation">;</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">cash</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">],</span> <span class="number">8U</span><span class="punctuation">);</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">(</span><span class="identifier">cash</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">],</span> <span class="number">4U</span><span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
<br />
<br />
<h3>
Celková suma</h3>
Nyní lze požadovat kód, který by co nejjednodušeji vracel celkovou hodnotu hotovosti v pokladně. Možným jednoduchým řešením je vrátit se k definici všech platidel a takto ji upravit:<br />
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">enum</span> <span class="enum name" style="color: #2b91af;">CzechMoney</span>
<span class="punctuation">{</span>
<span class="identifier">Kc1</span> <span class="operator">=</span> <span class="number">1</span><span class="punctuation">,</span>
<span class="identifier">Kc2</span> <span class="operator">=</span> <span class="number">2</span><span class="punctuation">,</span>
<span class="identifier">Kc5</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">,</span>
<span class="identifier">Kc10</span> <span class="operator">=</span> <span class="number">10</span><span class="punctuation">,</span>
<span class="identifier">Kc20</span> <span class="operator">=</span> <span class="number">20</span><span class="punctuation">,</span>
<span class="identifier">Kc50</span> <span class="operator">=</span> <span class="number">50</span><span class="punctuation">,</span>
<span class="identifier">Kc100</span> <span class="operator">=</span> <span class="number">100</span><span class="punctuation">,</span>
<span class="identifier">Kc200</span> <span class="operator">=</span> <span class="number">200</span><span class="punctuation">,</span>
<span class="identifier">Kc500</span> <span class="operator">=</span> <span class="number">500</span><span class="punctuation">,</span>
<span class="identifier">Kc1000</span> <span class="operator">=</span> <span class="number">1000</span><span class="punctuation">,</span>
<span class="identifier">Kc2000</span> <span class="operator">=</span> <span class="number">2000</span><span class="punctuation">,</span>
<span class="identifier">Kc5000</span> <span class="operator">=</span> <span class="number">5000</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
A poté doplnit do třídy <b>CzechCash</b> následující metodu:<br />
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">implicit</span> <span class="keyword" style="color: blue;">operator</span> <span class="keyword" style="color: blue;">decimal</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span> <span class="identifier">mc</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">decimal</span> <span class="identifier">sum</span> <span class="operator">=</span> <span class="number">0</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">foreach</span> <span class="punctuation">(</span><span class="identifier - keyword - (TRANSIENT)" style="color: blue;">var</span> <span class="identifier">what</span> <span class="keyword" style="color: blue;">in</span> <span class="identifier">mc</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Keys</span><span class="punctuation">)</span>
<span class="identifier">sum</span> <span class="operator">+=</span> <span class="punctuation">(</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">)</span> <span class="identifier">what</span> <span class="operator">*</span> <span class="identifier">mc</span><span class="operator">.</span><span class="identifier">cash</span><span class="punctuation">[</span><span class="identifier">what</span><span class="punctuation">];</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">sum</span><span class="punctuation">;</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
a tu si i ihned otestovat:<br />
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">CashSum</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cash1</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechCash</span><span class="punctuation">();</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc10</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">5</span><span class="punctuation">;</span>
<span class="identifier">cash1</span><span class="punctuation">[</span><span class="enum name - identifier - (TRANSIENT)" style="color: #2b91af;">CzechMoney</span><span class="operator">.</span><span class="identifier">Kc100</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="number">4</span><span class="punctuation">;</span>
<span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Assert</span><span class="operator">.</span><span class="identifier">AreEqual</span><span class="punctuation">((</span><span class="keyword" style="color: blue;">decimal</span><span class="punctuation">)</span><span class="identifier">cash1</span><span class="punctuation">,</span> <span class="number">450</span><span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
<br />
<b>Poznámka</b> - vše lze naprogramovat jednodušeji, pokud uchazeč ovládá Linq, tak místo několika řádků vyjádří vše jedním příkazem: <span class="keyword" style="color: blue;">return</span> <span class="identifier">mc</span><span class="operator">.</span><span class="identifier">cash</span><span class="operator">.</span><span class="identifier">Sum</span><span class="punctuation">(</span><span class="identifier">c</span> <span class="operator">=></span> <span class="punctuation">(</span><span class="keyword" style="color: blue;">int</span><span class="punctuation">)</span> <span class="identifier">c</span><span class="operator">.</span><span class="identifier">Key</span> <span class="operator">*</span> <span class="identifier">c</span><span class="operator">.</span><span class="identifier">Value</span><span class="punctuation">);</span><br />
<!-- START --><!-- END --><br />
<h3>
</h3>
<h3>
A co dál?</h3>
Samozřejmě, že zde práce nekončí, uchazeče lze požádat o řešení například pro euro, třídu lze následně upravit na gererickou. Dále lze mít informace o měnách uloženy v databázi a začít se bavit o IoC a DI a jak to vše dát dohromady - zkrátka na jednoduchém zadání lze vystavět poměrně pokročilé řešení.<br />
V uvedeném kódu mohou být chyby, je to skutečně jen ilustrace, jak lze k řešení úkolu přistoupit a jak lze rozsah zadání rozšiřovat a upřesňovat.</div>
<br />mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com4tag:blogger.com,1999:blog-2993762679677061763.post-63108390082777773852016-02-10T07:02:00.000+01:002016-02-10T07:02:36.323+01:00Vícevláknové zabíjení draků<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNql1CcL48F2sN3jGygyxdclXoJvrX9Ny0ExgbxMjZqPNWXAzTuStWKNIrzNzMlNi7gaqFqYZVg7JFeRynMUdqEU5s9kBPGM1bIXa7n8z9P8l43DBP61Fidx_cSD_WAv4cfaFt-xKwwTU/s1600/dragons.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNql1CcL48F2sN3jGygyxdclXoJvrX9Ny0ExgbxMjZqPNWXAzTuStWKNIrzNzMlNi7gaqFqYZVg7JFeRynMUdqEU5s9kBPGM1bIXa7n8z9P8l43DBP61Fidx_cSD_WAv4cfaFt-xKwwTU/s200/dragons.jpg" width="200" /></a>Jeden z nejlepších průvodců základy vícevláknového programování pro mne byl a vlastně pořád je web od Josepha Albahari na adrese <a href="http://www.albahari.com/threading/">http://www.albahari.com/threading/</a>.<br />
<br />
Stručný a jasný popis, navíc ke stažení jako pdf, i když napsaný před mnoha lety, tak pořád aktuální. A může být něco ještě lepšího?<br />
<br />
<br />
<a name='more'></a><br />
<br />
<br />
<div style="text-align: justify;">
Jako vhodný doplněk k zmíněným stránkám (i když to autoři asi nezamýšleli) se nyní objevila aplikace <b>The Deadlock Empire </b>na stránkách <a href="https://deadlockempire.github.io/">https://deadlockempire.github.io</a>/ </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Vtipně a zábavnou formou podané téma, které může pomoci pochopit nástrahy vícevláknového programování - a navíc tohle bylo napsáno Čechy (studenty) , kteří s touto hrou uspěli i v soutěži <a href="https://www.hackcambridge.com/">Hack Cambridge 2016</a>. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/eZp1qSF06uM/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/eZp1qSF06uM?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: justify;">
<br /></div>
<br />mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-74839230170177161352016-02-08T08:54:00.000+01:002016-02-08T09:59:37.293+01:00LINQ - cheat sheet<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkD80sPbj5iY_fDcTWmTkXVHBkx4jon9yeBdQNS-14Pzux9XpinrX0ZOqzAorspD5iESZrHWnxPkeYYlkaBJm7uLHXoQEYYzqhCjsufvaJwz3Tne5YeaMAeCMhaLqCkUJN5KFTAqbfW-8/s1600/LinqCheatSheet.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkD80sPbj5iY_fDcTWmTkXVHBkx4jon9yeBdQNS-14Pzux9XpinrX0ZOqzAorspD5iESZrHWnxPkeYYlkaBJm7uLHXoQEYYzqhCjsufvaJwz3Tne5YeaMAeCMhaLqCkUJN5KFTAqbfW-8/s1600/LinqCheatSheet.JPG" /></a>Ve třech příspěvcích v poslední době jsem zmínil použití LINQu - byl to příspěvek jak <a href="http://martinstrimpfl.blogspot.cz/2016/01/poznamky-z-code-review-vytvoreni-xml.html">vytvořit xml vstup pro SQL server</a>, pak popis <a href="http://martinstrimpfl.blogspot.cz/2016/01/hratky-s-linqem-aneb-distinct-petkrat.html">distinctu pěktrát jinak</a> a nakonec byl LINQ použit i v řešení úlohy z pohovoru v článku <a href="http://martinstrimpfl.blogspot.cz/2016/02/uspeli-by-jste-na-pohovoru-podruhe.html">Uspěli byste na pohovoru? Podruhé</a>. </div>
<div style="text-align: justify;">
LINQ je na jednu stranu jednoduchý prostředek pro práci s kolekcemi, na druhou stranu je velmi mocný a dovoluje jednoduše vyjádřit operace, které by jinak vyžadovali složitější zápis ve smyčkách. Nehledě na možnosti, které přináší při práci s data v databázích a datových souborech.</div>
<div style="text-align: justify;">
</div>
<a name='more'></a><br />
<div style="text-align: justify;">
Stručný přehled základních příkazů a možností použití je ke stažení v podobě A4 cheat sheetu <a href="https://drive.google.com/file/d/0B9dFsL8WUGzWNzdYYV9ZOHR1VGc/view?usp=sharing">zde</a>. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Mimo seznamu příkazů, u kterých je vyznačeno, zda se vykonávají okamžitě a nebo až je potřeba, je uvedena i základní syntaxe pro zápis spojovacích operací a ilustrované vysvětlení rozdílu mezi Gropu, Dictionary a Lookup.</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com2tag:blogger.com,1999:blog-2993762679677061763.post-76077692795387868222016-02-05T22:42:00.000+01:002016-03-06T17:03:29.089+01:00Uspěli byste na pohovoru? Podruhé...<div style="text-align: justify;">
Jednou za čas přibíráme do týmu nové lidi - což znamená hodně pohovorů s uchazeči. Jak jsem už napsal <a href="http://martinstrimpfl.blogspot.com/2015/06/uspeli-by-jste-na-pohovoru.html">tady</a>, tak spíše upřednostňuji rozhovor nad kouskem kódu - přitom se nejedná o žádné záludnosti. Uchazeč dostává také za úkol něco malého naprogramovat - jen je trochu potíž najít to správné zadání. Úkol by neměl být úplně triviální, ale zase nemůže být těžký. Většina lidí je navíc nervozní, ať již více čí méně a i to je třeba zohlednit. Takže následující úloha se může v případě, že si ji čtete doma, v klidu, jevit jako velmi jednoduchá, možná až primitivní.</div>
<span style="background-color: white; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13.2px; line-height: 18.48px; text-align: justify;"></span><br />
<a name='more'></a><br />
<span style="background-color: white; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13.2px; line-height: 18.48px; text-align: justify;">Napište validační metodu, která vezme kolekci telefonních čísel a rozhodne, zda se čísla navzájem nevylučují, tedy například seznam:</span><br />
<span style="background-color: white; font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif; font-size: 13.2px; line-height: 18.48px; text-align: justify;"><br /></span>
<br />
<div style="text-align: justify;">
<span style="font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: white; font-size: 13.2px; line-height: 18.48px;"><b>89 59 87, 85 59 88, 855</b></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: white; font-size: 13.2px; line-height: 18.48px;"><br /></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: white; font-size: 13.2px; line-height: 18.48px;">nebude validní, neboť poslední číslo je shodné se začátkem druhého čísla a tedy by nebylo možné toto druhé číslo zavolat, neboť po zadání třetího čísla by došlo ke spojení s číslem třetím (855).</span></span></div>
<div style="text-align: justify;">
<span style="font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: white; font-size: 13.2px; line-height: 18.48px;"><br /></span></span></div>
<div style="text-align: justify;">
<span style="font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: white; font-size: 13.2px; line-height: 18.48px;">Seznam:</span></span></div>
<div style="text-align: justify;">
<span style="font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: white; font-size: 13.2px; line-height: 18.48px;"><b>78 89 59, 78 89 56, 455, 787, 797</b></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "arial" , "tahoma" , "helvetica" , "freesans" , sans-serif;"><span style="background-color: white; font-size: 13.2px; line-height: 18.48px;">naopak platný je.</span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Vstupní seznam je vždy kolekce řetězců a ty vždy obsahují jen čísla, tedy například:</div>
<div style="text-align: justify;">
<br /></div>
<pre><code><span class="keyword" style="color: blue;">new</span><span class="punctuation">[]</span> <span class="punctuation">{</span> <span class="string" style="color: #a31515;">"788959"</span><span class="punctuation">,</span> <span class="string" style="color: #a31515;">"788956"</span><span class="punctuation">,</span> <span class="string" style="color: #a31515;">"455"</span><span class="punctuation">,</span> <span class="string" style="color: #a31515;">"787"</span><span class="punctuation">,</span> <span class="string" style="color: #a31515;">"797"</span> <span class="punctuation">}</span></code></pre>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Určitě existuje spousta řešení, některá elegantní, některá zase výkonná, a po určitých zkušenostech si troufám říci, že každý to řeší jinak.<br />
<br />
Nabízím tady jedno možné řešení, ale netroufám si tvrdit, že je nejlepší - ostatně ono stačí, když si řešitel jakkoli poradí.<br />
<br />
Klikněte <a href="#" onclick="toggle_visibility('codeExampleToShow');return false;">tady</a> a ukáže se kód.</div>
<div id="codeExampleToShow" style="display: none;">
<pre><code><span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">bool</span> <span class="identifier">ValidPhoneList</span><span class="punctuation">(</span><span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">IEnumerable</span><span class="punctuation"><</span><span class="keyword" style="color: blue;">string</span><span class="punctuation">></span> <span class="identifier">phoneNumbers</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">phoneNumbersByLength</span>
<span class="operator">=</span> <span class="identifier">phoneNumbers</span>
<span class="operator">.</span><span class="identifier">GroupBy</span><span class="punctuation">(</span><span class="identifier">phoneNumber</span> <span class="operator">=></span> <span class="identifier">phoneNumber</span><span class="operator">.</span><span class="identifier">Length</span><span class="punctuation">)</span>
<span class="operator">.</span><span class="identifier">OrderBy</span><span class="punctuation">(</span><span class="identifier">group</span> <span class="operator">=></span> <span class="identifier">group</span><span class="operator">.</span><span class="identifier">Key</span><span class="punctuation">);</span>
<span class="keyword" style="color: blue;">return</span> <span class="operator">!</span><span class="identifier">phoneNumbersByLength</span>
<span class="operator">.</span><span class="identifier">Any</span><span class="punctuation">(</span><span class="identifier">group</span> <span class="operator">=></span> <span class="identifier">phoneNumbers</span>
<span class="operator">.</span><span class="identifier">Any</span><span class="punctuation">(</span>
<span class="identifier">phoneNumber</span> <span class="operator">=></span> <span class="identifier">phoneNumber</span><span class="operator">.</span><span class="identifier">Length</span> <span class="operator">></span> <span class="identifier">group</span><span class="operator">.</span><span class="identifier">Key</span>
<span class="operator">&&</span>
<span class="identifier">group</span><span class="operator">.</span><span class="identifier">Any</span><span class="punctuation">(</span><span class="identifier">groupedPhone</span> <span class="operator">=></span>
<span class="identifier">phoneNumber</span><span class="operator">.</span><span class="identifier">Substring</span><span class="punctuation">(</span><span class="number">0</span><span class="punctuation">,</span> <span class="identifier">group</span><span class="operator">.</span><span class="identifier">Key</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">Equals</span><span class="punctuation">(</span><span class="identifier">groupedPhone</span><span class="punctuation">))</span>
<span class="punctuation">)</span>
<span class="punctuation">);</span>
<span class="punctuation">}</span></code></pre>
</div>
<script>
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
</script>mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com7tag:blogger.com,1999:blog-2993762679677061763.post-12126457721437040362016-02-05T08:42:00.000+01:002016-02-05T09:51:06.325+01:00Monitor pro vývojáře<div style="text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4wcoz7-DOs_hB9I14hL_MhKGJu-iQDzZfdzA178b18oJbAjA2sDJIjaTLMbpRUfxW86KxGsnSS46e-EMoZhNRkEqgV-LwpUR_62AZqnc9XyB_oldeIGLkcPUl_T4aqgVzG4_2HGXA_LA/s1600/dell.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4wcoz7-DOs_hB9I14hL_MhKGJu-iQDzZfdzA178b18oJbAjA2sDJIjaTLMbpRUfxW86KxGsnSS46e-EMoZhNRkEqgV-LwpUR_62AZqnc9XyB_oldeIGLkcPUl_T4aqgVzG4_2HGXA_LA/s1600/dell.jpg" /></a>Nedávno jsem si <a href="http://martinstrimpfl.blogspot.com/2015/07/jaky-vybrat-notebook-pro-vyvojare-v-netc.html">vybral laptop</a>, nyní jsem si chtěl dopřát i lepší externí monitor - obrazovka laptopu je malá a pohodlí práce před velkým monitorem je k nezaplacení. U výběru pracovního monitoru ale mám jasno - už dlouho používám jen monitory značky Dell a řady Ultrasharp. Poměr cena a užitná hodnota mi u nich přišel vždy nejlepší, navíc polohovatelný stojan je pro práci příjemný, stejně jako možnost natočit si třeba druhý monitor "na výšku".<br />
<a name='more'></a><br />
Výběr monitoru byl tak pro mně snadnější než laptopu, stačí si jen vybrat to správné rozlišeni. S ním je to asi takhle:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<ul>
<li style="text-align: justify;"><b>1920 na 1080</b> - "klasické" full HD rozlišení. Myslím, že pro vývojáře a vůbec lidi, co píší a tvoří, je důležité vertikální rozlišení a to je v tomto případě nízké. Pro filmy, web či hraní her to ale špatné není, monitory se nabízí v široké škále uhlopříček od 22 do 27 palců. Ve Visual Studiu se vejde na obrazovku cca 53 řádků.</li>
<li><br /></li>
<li style="text-align: justify;"><b>1920 na 1200</b> - dřívější standard, dnes ale postupně na ústupu, většinou se jedná o kousky nabízené jen v jediné uhlopříčce 24 palců. Dle mého názoru nic menšího než 1200px není pro vývojáře vhodné. Je prostě lepší vidět více řádků, tady se jich nabízí 64.</li>
<li><br /></li>
<li style="text-align: justify;"><b>2560 na 1440</b> - poměrně lákavé rozlišení, malý příplatek k předchozímu rozlišení a nepoměrně větší plocha. Uhlopříčky se pohybují od 24 do 32 palců. Na obrazovku se ve Visual Studio vejde 73 řádků. </li>
</ul>
<br />
<div style="text-align: justify;">
Záměrně neuvádím rozlišení 4K - myslím, že dnes je pořád ještě zbytečné, může přinášet problémy s grafickou kartou či obnovovací frekvencí, navíc monitory jsou drahé - u takto vysokého rozlišení buď budete mít hladké písmo, ale pracovní rozlišení bude srovnatelné s klasickým full HD monitorem a nebo si musíte koupit vyšší uhlopříčku - což znamená utratit 20 a více tisíc korun za jeden monitor. To už je lepší si koupit dva monitory o nižším rozlišení - pokud vám tedy nebudou překážet na stole.<br />
<br />
<div style="text-align: left;">
Ale samozřejmě existují i jiné pohledy na tento problém, třeba Jeff Attwood si 4K chválí a i používá, dokonce ve více kusech, více se o tom lze dočíst tady: <a href="http://blog.codinghorror.com/our-brave-new-world-of-4k-displays/">http://blog.codinghorror.com/our-brave-new-world-of-4k-displays/</a></div>
</div>
<div style="text-align: justify;">
<h3>
<br /></h3>
<h3>
Jak jsem vybíral</h3>
</div>
<div style="text-align: justify;">
Při výběru jsem rovnou zavrhl monitory s klasickým Full HD rozlišením. V kategori 16:10 je pak výběr širší, ale ceny jsou již vyšší - kolem 6 až 8 tisíc za 24 palcové zařízení, v nabídce je i pěkný a elegantní U2415.<br />
<br /></div>
<div style="text-align: justify;">
Nakonec jsem našel monitor 25 palc U2515, který je zhruba o 1000 korun dražší než monitory 1920 na 1200 px a za cenu cca 8500 Kč si tak lze koupit polohovatelný monitor s možností natáčení zobrazovací plochy, s USB rozbočovačem a pod.<br />
<br />
Dell nabízí nejmenší monitor s tímto rozlišením v uhlopříčce 24 palců, ale tam jsem se trochu obával titěrnosti zobrazení - a naopak monitory s větší uhlopříčkou o velikosti 27 palců jsou už cenově mimo můj rozpočet - ceny začínají na 12 tisících a to už je cenové pásmo, kde je možné nalézt i v něčem lepší kousky jiných výrobců, například 32 palcový BenQ 3200PT s VA technologií, tedy o poznání lepším kontrastem (ale zase tahle technologie není příliš vhodná pro hráče)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Velkou výhodou vysokého rozlišení je možnost mít vedle sebe otevřené dva programy, například Visual Studio a prohlížeč. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Pro Visual Studio stačí ovládat klávesové zkratky a není tak nutné mít otevřené okna jako Solution, Project či Properties.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Navigační lištu (taskbar) Windows mám na pravé straně zobrazovací plochy, je to podle mého lepší místo než dole. Schovávat si ji moc nechci, nikdy jsem si na to nezvykl. Pro umístnění k boční svislé hraně monitoru mluví i to, že horizontální rozlišení je dostatečné a tak je potřeba spíše šetřit místem na výšku.<br />
<br />
Při horizontálním rozlišení 2560px je tak na obrazovce dost místa na dvě okna programů, tady je třeba ukázka současně otevřeného okna Visual Studia a prohlížeče Chrome s aktivovanými DevTools:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNwuKdrp_LsK3Eo5rNMIAkd40BkcVboLs6w7YEfGmITmconC2thjmBUbjYO5L4xrNcqirw0rMuFRxXZj5hqS1bqTdFBgieDY4QBRJ0JetWQgYxFXevYNh7RERSSIeLfsYMzo6ZUIdM_ew/s1600/2560screen.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNwuKdrp_LsK3Eo5rNMIAkd40BkcVboLs6w7YEfGmITmconC2thjmBUbjYO5L4xrNcqirw0rMuFRxXZj5hqS1bqTdFBgieDY4QBRJ0JetWQgYxFXevYNh7RERSSIeLfsYMzo6ZUIdM_ew/s640/2560screen.jpg" width="640" /></a></div>
<br />
což si lze porovnat s rozložením při 1920 na 1200 px:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqecFB0T7VbR2iJJh-2R3WHmsLYuGlhnANHTPSmrO81UAin7Ftpc4bQI1b04xk9MiYWZM8Rn0qnqkb5eo33rjG7Y73PBcw4st0PCP6Dzyg-2tSTBylA1zM4vzQFlRbwHr0kWtVNhkYX-s/s1600/1200Screen.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqecFB0T7VbR2iJJh-2R3WHmsLYuGlhnANHTPSmrO81UAin7Ftpc4bQI1b04xk9MiYWZM8Rn0qnqkb5eo33rjG7Y73PBcw4st0PCP6Dzyg-2tSTBylA1zM4vzQFlRbwHr0kWtVNhkYX-s/s400/1200Screen.jpg" width="400" /></a></div>
<br />
<br />
a pro porovnání ještě snímek obrazovky ve full HD (1920 na 1080) rozlišení<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDZlvhkT4O5MqWMmya7F_9OpTXENGBb53PlqDdYcNp80mDPKcNNsHVpH4SVUNf9DPfB97g_HaxjJJ9ybvCVHdxrDYYgBg9FDGekgkkg7gNuZUN2v_6Yp0DWGzZhsNpjhCeRmEC6fJeBS0/s1600/1080screen.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="226" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDZlvhkT4O5MqWMmya7F_9OpTXENGBb53PlqDdYcNp80mDPKcNNsHVpH4SVUNf9DPfB97g_HaxjJJ9ybvCVHdxrDYYgBg9FDGekgkkg7gNuZUN2v_6Yp0DWGzZhsNpjhCeRmEC6fJeBS0/s400/1080screen.jpg" width="400" /></a></div>
<br /></div>
<div style="text-align: justify;">
Okna si lze snadno přesouvat a umístnít do rohů obrazovky pomocí klávesy Windows a kurzorových šipek.<br />
<br /></div>
<div style="text-align: justify;">
<h3>
Problém pod Windows 10</h3>
</div>
<div style="text-align: justify;">
Můj laptop (Toshiba Portégé - viz <a href="http://martinstrimpfl.blogspot.com/2015/07/jaky-vybrat-notebook-pro-vyvojare-v-netc.html">tady</a> a <a href="http://martinstrimpfl.blogspot.com/2016/01/toshiba-leading-innovation-in-cheating.html">tady</a>) po připojení přes HDMI neměl s rozlišením žádný problém, i když se to nikde v jeho specifikacích přímo nepíše, bez problému se s ním vypořádal s obnovovací frekvencí 60 Hz.</div>
<div style="text-align: justify;">
<br />
Horší to bylo s celkovým nastavením obrazu ve WIndows 10. Při klasickém nastavení, tj. 100%, působilo písmo rozmazaně a bylo nutné nastavit zvětšení obrazovky na 125%. Pak je sice vše krásné (a velké), ale přichází se o rozlišení, Ve Visual Studiu lze nastavit menší velikost fontu (z 10 na 8) a pořád je to krásně čitelné, ale i tak je celkový počet řádků něco kolem 67, celkový dojem je tedy srovnatelný s rozlišením 1920 na 1200, jen písmo je pochopitelně hladší.<br />
<br />
Také se musí vypnout synchronizace nastavení Visual Studia, neboť pokud by jste pracovali na více strojích a pod stejným účtem, přenese se nastavení i do dalších VS a tam může být menší font již nečitelný.</div>
<div style="text-align: justify;">
<br />
Nakonec jsem ale našel program, který mikrosoftí nastavení zobrazení upraví a je tak možné při normálním poměru mít písmo krásně hladké a ostré a využít tedy naplno vyšší rozlišení. Nechápu, proč tohle Microsoft neopraví sám a je nutné používat takovéto přístupy - utilitka se jmenuje Windows 10 DPI Fix, více informací lze nalézt v diskuzi <a href="http://www.tenforums.com/general-discussion/7423-blurry-text.html">zde</a> a nebo shlédnout krátké video:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/zCu9TFKuLyY/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/zCu9TFKuLyY?feature=player_embedded" width="320"></iframe></div>
<br />
<h3>
Co mi na monitoru zatím vadí</h3>
Monitor má dvě velké nedomyšlenosti - senzorové ovládání a umístnění USB portů. Senzorové ovládání není tak pohodlné a chybí jistota stisku tlačítka. Monitor se přes senzorové tlačítko i zapíná a to s mírnou prodlevou - postrádám tedy jistotu, že jsem monitor skutečně zapnul.<br />
<br />
Umístění USB portu - až na jeden jsou všechny ostatní výstupy USB rozbočovače schované na zadní části monitoru vedle připojovacích kabelů, navíc je toto místo chráněno plastovou krytkou. Zapojovaní jakéhokoliv USB zařízení je tedy krkolomné a nepohodlné, postrádám tady původní přivětivé řešení starších Ultrasharpů s vyvedenými USB konektory a čtečkou karet na levou hranu monitoru.<br />
<br />
Ale až na tyto připomínky je monitor velmi příjemný na oči a to jak při práci, tak na pohled, tenčí rámeček kolem displeje je elegantní.</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-32857193250154063442016-02-01T22:56:00.000+01:002016-02-01T23:13:59.388+01:00Visual Studio 2015 - deset zajímavých rozšíření<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcdnrVbjAH4A4ZSgTt47wCg1zdlmvGCylaPnQ_vQqJuq-vQVZ7PiWpgj3TcxLEXqPCH2oFKsL1sDC8CFBHC3r2JCgo33du3adjMprAmIFmM0zlrljfA8TaTjrkM9LqFsatoNPUXiMQ_Is/s1600/vslogo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcdnrVbjAH4A4ZSgTt47wCg1zdlmvGCylaPnQ_vQqJuq-vQVZ7PiWpgj3TcxLEXqPCH2oFKsL1sDC8CFBHC3r2JCgo33du3adjMprAmIFmM0zlrljfA8TaTjrkM9LqFsatoNPUXiMQ_Is/s1600/vslogo.jpg" /></a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAN0AAADkCAMAAAArb9FNAAAAjVBMVEX///9oIXpcAHBfAHLi2eVnHnlXAGzh1+RmHHjLu9BjE3ZlGHfj2uWATo7MvNFWAGz28/drJnzTxdd4QYimiK9hDHTXy9vBrceceqdzN4Po4eqFV5O7pcKPZpuXcqJ8R4u1nb3v6vGoi7GhgatuLX90OYR5Q4m+qcWDU5Guk7aNY5n59vlQAGeSbJ6adqWL0NlTAAAHq0lEQVR4nO2d7VqjMBCF+RCKwbqtStV2V61aV7fq/V/ephVrS4FkJpMP8uT8Vsr7ZIAkZ2YSRUFBQUFBQUFBQUFBQUFBQRSa353YvgV9mqdVsrq2fReaNE+LOC7S5MbHATxLONxGLLm9Xtu+G2KdJFn8Le8GcJT/wH0NoEdP4KwBVw/gyPZ9kWiWN9l2T6DtW1PXRTucH0/g+a8uOA8G8LQXbuBP4HVnWHowgH9l4LYDmA/vCfwtCTfIAXwAwMVDewLfEhDcsAbwEQ63HcD3ue07l9AVCo4rGcDr5QkLFydntu9dqBs03ADG7i5Fw7lP96EA5zzdPxU41+kWlQqc43SvanBu040V4Zymu1eFc5nukqnCOUy3Uodzlm59SwDnKt36mQLOUbrJtKSAc5NuktHAOUm3LIngXKRbVgURnIN0y5QMzj26eXpk8vhDN0/oRs45urOEcORco2saq17RtRir/tB1GKt+0HUbqx7Q9Ruruulmej0HobGqk270mid3GuGkjFVNdJyNT2yr5+Ww4KToRov8a9JeJKd64CDGKi3djm2j/EYHHNBYpaM72WfjSlf00YkwVmnoTt6bC8kyuSCGwxmrJHTHv5zlV6RwaGNVCx2PzpcJHRzeWNVEF5fpjApOwVjVRcej840GTsVY1UbHo3NMkZGsZKxqpItZpZ7L80czHJ6OR+eDIpyaa6yXjv/vQglO0TWWouvPV+mli1mpsDpEGasZzDxRoouL/DcWDmWssukjCE+Njv//PxzcC8bB4o/COehZVaWLWYzJo8MYq9tAOTVLx38UvCWBMlZZublV03T8Gh9AOIyxWj8C5umAWxJrhLG6e31ZoOM/Lr8lgTFWWfZ9mzbo+HVktyQwxurei9kOXVzdSkUnwljN8r8//2+JLi6Tcwk4uLFaHXxygHQK88ym8icR3BwOl/w5uII9uji97N+SgBurRx9Ti3Q8Ovu2JE7Axmo1bU6EbNLxN8Bj57VGYLiWaYJeukw0te/ckgC7xq1TPFK6swZdthL6Gax9wwzsGlfPbdNzvXTP0bnoNlu3JMDGaoefpjUys+nm+RG9+ZJFMzrPgXCdUzvtdNGciSZTjB1e9hQI1z0t108XTYRLmOxgSwIKl3923pABOpktn72ZL9BYLfs8UCN0EhutLKvfeUBjtX86boZOwrupv1dAY1Xg7hqik7nrzVzjDQQnXGiYouPvCuH3ubqFGauV0Lc2RhfNxFP+ArQ/JF5CGaSL5hVVevZGUstfg3QSHz55iRaH5uko6qzqC0tEpXk6IhNOOk/EMB1J0oJ8FoVpOvU8KEgGjHE68CS5oTIFZC+Zp+PrboUigvQekttjgS6ap9gPX982kyt00WSK+/CBs5as0PEVHyY4i1doTo9eurjrDwtUoUQJTYe0QnfxC1kFIjlFsUqnkLQtXvQYpGt97mAr1IaklgYW6VTnYpDoNB6Z6pl6gFRy03TKjTRiSCq5WTqajgXy0WmUbklV9y65NKelG/XTIXzwTslFp8Gxo63klNp8MDd2Euu6EvRUSkSnMToJfyBdfILuRhydpujEFS7bqgVYxYFwE8IQ3YcQrl67AatFBNFphm4h/JXdPhdwotYfnUboLoUTlL0QA1Zp9UYnkK6/IqSdTrzPcDgA0PLBnu1N/d87sTnSXLRBtzy7o1M7nTij49g/heJ1RidpZLbQCTcZWiubZXtZ79QRnXrpnoUTlI5cE/DmRHt0aqUTZ8F1dhQA78e3buTqpROor/QCmk3Vuglvk44dZYvuC95i5Hir2iJdI4f5SPAV01F0WqMr9jPr24XoW9SITlt0X1VIIjx4z6nD6LREJ1kmimipdRCdVujkS3wx7dD2ohNYXUhCBynPxvTp+4lOC3QpyIbD9FjcRSeQTr0eAdwWAdUfs45O03SIlhaTGIH39TuG6WApC7Uw5ZNfMWKUDttKBtdTOB2vLwzSKbQBQjW7ZuUVrJpeha5aKTTJQTUqh3ZCUKCDOvoNUSU/aqErQH53myh8TSW65o7fjyja3mnvQYKlo2lZqLt/DI4O0duhXZp7/6DojstR0dLbtwlDB+1a0atPi93SWugkNhhA0tkvTUR31KWQFdSnrmls5CfqMDkaJwd82E4/fdLXhFGiO+gen3oPsVZpa6Ap09l19s3HmKazHHU1P5XsyrvlS49KkcmkqXGtdEflcULVd7FVNjsqbzQj65nZqmub3bD1y24nc+26oMdziM7vEwQ8P/3B85M7PD91xfMTc2iTkd2jozyGy0G6aClsTjNkumhSeHxCHN3RhW7SUR076SgdVQGOo3Q0x726S4frKD0YOgoHzGE65fO/hfkqdiUuehgynbID5jadqgPmOJ3isSyu06lZRM7TKVWzu0+n4oANgE7BIhoCHd4iGgQd0iIq0ndqn1iPwEVSccySld5TTgkFdMCKNHmSKCBwRpAiKZZfDmbYask6YEMbtlpSRVIDHLZaQotooMNWqx+P5S+aDts1pO4iqZIP2zA+bj3qcMBYfj/sYavV4oCVaXo1+GGr1SiSynwZtlr7DphPw1bru0gqq/KxT8NWa1skxYft0bNhq7Wepl4OW62Jb09bUFBQUFBQUFBQUFBQUNBO/wE/I5YvY9IQbQAAAABJRU5ErkJggg==" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
<div style="text-align: justify;">
<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAN0AAADkCAMAAAArb9FNAAAAjVBMVEX///9oIXpcAHBfAHLi2eVnHnlXAGzh1+RmHHjLu9BjE3ZlGHfj2uWATo7MvNFWAGz28/drJnzTxdd4QYimiK9hDHTXy9vBrceceqdzN4Po4eqFV5O7pcKPZpuXcqJ8R4u1nb3v6vGoi7GhgatuLX90OYR5Q4m+qcWDU5Guk7aNY5n59vlQAGeSbJ6adqWL0NlTAAAHq0lEQVR4nO2d7VqjMBCF+RCKwbqtStV2V61aV7fq/V/ephVrS4FkJpMP8uT8Vsr7ZIAkZ2YSRUFBQUFBQUFBQUFBQUFBQRSa353YvgV9mqdVsrq2fReaNE+LOC7S5MbHATxLONxGLLm9Xtu+G2KdJFn8Le8GcJT/wH0NoEdP4KwBVw/gyPZ9kWiWN9l2T6DtW1PXRTucH0/g+a8uOA8G8LQXbuBP4HVnWHowgH9l4LYDmA/vCfwtCTfIAXwAwMVDewLfEhDcsAbwEQ63HcD3ue07l9AVCo4rGcDr5QkLFydntu9dqBs03ADG7i5Fw7lP96EA5zzdPxU41+kWlQqc43SvanBu040V4Zymu1eFc5nukqnCOUy3Uodzlm59SwDnKt36mQLOUbrJtKSAc5NuktHAOUm3LIngXKRbVgURnIN0y5QMzj26eXpk8vhDN0/oRs45urOEcORco2saq17RtRir/tB1GKt+0HUbqx7Q9Ruruulmej0HobGqk270mid3GuGkjFVNdJyNT2yr5+Ww4KToRov8a9JeJKd64CDGKi3djm2j/EYHHNBYpaM72WfjSlf00YkwVmnoTt6bC8kyuSCGwxmrJHTHv5zlV6RwaGNVCx2PzpcJHRzeWNVEF5fpjApOwVjVRcej840GTsVY1UbHo3NMkZGsZKxqpItZpZ7L80czHJ6OR+eDIpyaa6yXjv/vQglO0TWWouvPV+mli1mpsDpEGasZzDxRoouL/DcWDmWssukjCE+Njv//PxzcC8bB4o/COehZVaWLWYzJo8MYq9tAOTVLx38UvCWBMlZZublV03T8Gh9AOIyxWj8C5umAWxJrhLG6e31ZoOM/Lr8lgTFWWfZ9mzbo+HVktyQwxurei9kOXVzdSkUnwljN8r8//2+JLi6Tcwk4uLFaHXxygHQK88ym8icR3BwOl/w5uII9uji97N+SgBurRx9Ti3Q8Ovu2JE7Axmo1bU6EbNLxN8Bj57VGYLiWaYJeukw0te/ckgC7xq1TPFK6swZdthL6Gax9wwzsGlfPbdNzvXTP0bnoNlu3JMDGaoefpjUys+nm+RG9+ZJFMzrPgXCdUzvtdNGciSZTjB1e9hQI1z0t108XTYRLmOxgSwIKl3923pABOpktn72ZL9BYLfs8UCN0EhutLKvfeUBjtX86boZOwrupv1dAY1Xg7hqik7nrzVzjDQQnXGiYouPvCuH3ubqFGauV0Lc2RhfNxFP+ArQ/JF5CGaSL5hVVevZGUstfg3QSHz55iRaH5uko6qzqC0tEpXk6IhNOOk/EMB1J0oJ8FoVpOvU8KEgGjHE68CS5oTIFZC+Zp+PrboUigvQekttjgS6ap9gPX982kyt00WSK+/CBs5as0PEVHyY4i1doTo9eurjrDwtUoUQJTYe0QnfxC1kFIjlFsUqnkLQtXvQYpGt97mAr1IaklgYW6VTnYpDoNB6Z6pl6gFRy03TKjTRiSCq5WTqajgXy0WmUbklV9y65NKelG/XTIXzwTslFp8Gxo63klNp8MDd2Euu6EvRUSkSnMToJfyBdfILuRhydpujEFS7bqgVYxYFwE8IQ3YcQrl67AatFBNFphm4h/JXdPhdwotYfnUboLoUTlL0QA1Zp9UYnkK6/IqSdTrzPcDgA0PLBnu1N/d87sTnSXLRBtzy7o1M7nTij49g/heJ1RidpZLbQCTcZWiubZXtZ79QRnXrpnoUTlI5cE/DmRHt0aqUTZ8F1dhQA78e3buTqpROor/QCmk3Vuglvk44dZYvuC95i5Hir2iJdI4f5SPAV01F0WqMr9jPr24XoW9SITlt0X1VIIjx4z6nD6LREJ1kmimipdRCdVujkS3wx7dD2ohNYXUhCBynPxvTp+4lOC3QpyIbD9FjcRSeQTr0eAdwWAdUfs45O03SIlhaTGIH39TuG6WApC7Uw5ZNfMWKUDttKBtdTOB2vLwzSKbQBQjW7ZuUVrJpeha5aKTTJQTUqh3ZCUKCDOvoNUSU/aqErQH53myh8TSW65o7fjyja3mnvQYKlo2lZqLt/DI4O0duhXZp7/6DojstR0dLbtwlDB+1a0atPi93SWugkNhhA0tkvTUR31KWQFdSnrmls5CfqMDkaJwd82E4/fdLXhFGiO+gen3oPsVZpa6Ap09l19s3HmKazHHU1P5XsyrvlS49KkcmkqXGtdEflcULVd7FVNjsqbzQj65nZqmub3bD1y24nc+26oMdziM7vEwQ8P/3B85M7PD91xfMTc2iTkd2jozyGy0G6aClsTjNkumhSeHxCHN3RhW7SUR076SgdVQGOo3Q0x726S4frKD0YOgoHzGE65fO/hfkqdiUuehgynbID5jadqgPmOJ3isSyu06lZRM7TKVWzu0+n4oANgE7BIhoCHd4iGgQd0iIq0ndqn1iPwEVSccySld5TTgkFdMCKNHmSKCBwRpAiKZZfDmbYask6YEMbtlpSRVIDHLZaQotooMNWqx+P5S+aDts1pO4iqZIP2zA+bj3qcMBYfj/sYavV4oCVaXo1+GGr1SiSynwZtlr7DphPw1bru0gqq/KxT8NWa1skxYft0bNhq7Wepl4OW62Jb09bUFBQUFBQUFBQUFBQUNBO/wE/I5YvY9IQbQAAAABJRU5ErkJggg==" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAN0AAADkCAMAAAArb9FNAAAAjVBMVEX///9oIXpcAHBfAHLi2eVnHnlXAGzh1+RmHHjLu9BjE3ZlGHfj2uWATo7MvNFWAGz28/drJnzTxdd4QYimiK9hDHTXy9vBrceceqdzN4Po4eqFV5O7pcKPZpuXcqJ8R4u1nb3v6vGoi7GhgatuLX90OYR5Q4m+qcWDU5Guk7aNY5n59vlQAGeSbJ6adqWL0NlTAAAHq0lEQVR4nO2d7VqjMBCF+RCKwbqtStV2V61aV7fq/V/ephVrS4FkJpMP8uT8Vsr7ZIAkZ2YSRUFBQUFBQUFBQUFBQUFBQRSa353YvgV9mqdVsrq2fReaNE+LOC7S5MbHATxLONxGLLm9Xtu+G2KdJFn8Le8GcJT/wH0NoEdP4KwBVw/gyPZ9kWiWN9l2T6DtW1PXRTucH0/g+a8uOA8G8LQXbuBP4HVnWHowgH9l4LYDmA/vCfwtCTfIAXwAwMVDewLfEhDcsAbwEQ63HcD3ue07l9AVCo4rGcDr5QkLFydntu9dqBs03ADG7i5Fw7lP96EA5zzdPxU41+kWlQqc43SvanBu040V4Zymu1eFc5nukqnCOUy3Uodzlm59SwDnKt36mQLOUbrJtKSAc5NuktHAOUm3LIngXKRbVgURnIN0y5QMzj26eXpk8vhDN0/oRs45urOEcORco2saq17RtRir/tB1GKt+0HUbqx7Q9Ruruulmej0HobGqk270mid3GuGkjFVNdJyNT2yr5+Ww4KToRov8a9JeJKd64CDGKi3djm2j/EYHHNBYpaM72WfjSlf00YkwVmnoTt6bC8kyuSCGwxmrJHTHv5zlV6RwaGNVCx2PzpcJHRzeWNVEF5fpjApOwVjVRcej840GTsVY1UbHo3NMkZGsZKxqpItZpZ7L80czHJ6OR+eDIpyaa6yXjv/vQglO0TWWouvPV+mli1mpsDpEGasZzDxRoouL/DcWDmWssukjCE+Njv//PxzcC8bB4o/COehZVaWLWYzJo8MYq9tAOTVLx38UvCWBMlZZublV03T8Gh9AOIyxWj8C5umAWxJrhLG6e31ZoOM/Lr8lgTFWWfZ9mzbo+HVktyQwxurei9kOXVzdSkUnwljN8r8//2+JLi6Tcwk4uLFaHXxygHQK88ym8icR3BwOl/w5uII9uji97N+SgBurRx9Ti3Q8Ovu2JE7Axmo1bU6EbNLxN8Bj57VGYLiWaYJeukw0te/ckgC7xq1TPFK6swZdthL6Gax9wwzsGlfPbdNzvXTP0bnoNlu3JMDGaoefpjUys+nm+RG9+ZJFMzrPgXCdUzvtdNGciSZTjB1e9hQI1z0t108XTYRLmOxgSwIKl3923pABOpktn72ZL9BYLfs8UCN0EhutLKvfeUBjtX86boZOwrupv1dAY1Xg7hqik7nrzVzjDQQnXGiYouPvCuH3ubqFGauV0Lc2RhfNxFP+ArQ/JF5CGaSL5hVVevZGUstfg3QSHz55iRaH5uko6qzqC0tEpXk6IhNOOk/EMB1J0oJ8FoVpOvU8KEgGjHE68CS5oTIFZC+Zp+PrboUigvQekttjgS6ap9gPX982kyt00WSK+/CBs5as0PEVHyY4i1doTo9eurjrDwtUoUQJTYe0QnfxC1kFIjlFsUqnkLQtXvQYpGt97mAr1IaklgYW6VTnYpDoNB6Z6pl6gFRy03TKjTRiSCq5WTqajgXy0WmUbklV9y65NKelG/XTIXzwTslFp8Gxo63klNp8MDd2Euu6EvRUSkSnMToJfyBdfILuRhydpujEFS7bqgVYxYFwE8IQ3YcQrl67AatFBNFphm4h/JXdPhdwotYfnUboLoUTlL0QA1Zp9UYnkK6/IqSdTrzPcDgA0PLBnu1N/d87sTnSXLRBtzy7o1M7nTij49g/heJ1RidpZLbQCTcZWiubZXtZ79QRnXrpnoUTlI5cE/DmRHt0aqUTZ8F1dhQA78e3buTqpROor/QCmk3Vuglvk44dZYvuC95i5Hir2iJdI4f5SPAV01F0WqMr9jPr24XoW9SITlt0X1VIIjx4z6nD6LREJ1kmimipdRCdVujkS3wx7dD2ohNYXUhCBynPxvTp+4lOC3QpyIbD9FjcRSeQTr0eAdwWAdUfs45O03SIlhaTGIH39TuG6WApC7Uw5ZNfMWKUDttKBtdTOB2vLwzSKbQBQjW7ZuUVrJpeha5aKTTJQTUqh3ZCUKCDOvoNUSU/aqErQH53myh8TSW65o7fjyja3mnvQYKlo2lZqLt/DI4O0duhXZp7/6DojstR0dLbtwlDB+1a0atPi93SWugkNhhA0tkvTUR31KWQFdSnrmls5CfqMDkaJwd82E4/fdLXhFGiO+gen3oPsVZpa6Ap09l19s3HmKazHHU1P5XsyrvlS49KkcmkqXGtdEflcULVd7FVNjsqbzQj65nZqmub3bD1y24nc+26oMdziM7vEwQ8P/3B85M7PD91xfMTc2iTkd2jozyGy0G6aClsTjNkumhSeHxCHN3RhW7SUR076SgdVQGOo3Q0x726S4frKD0YOgoHzGE65fO/hfkqdiUuehgynbID5jadqgPmOJ3isSyu06lZRM7TKVWzu0+n4oANgE7BIhoCHd4iGgQd0iIq0ndqn1iPwEVSccySld5TTgkFdMCKNHmSKCBwRpAiKZZfDmbYask6YEMbtlpSRVIDHLZaQotooMNWqx+P5S+aDts1pO4iqZIP2zA+bj3qcMBYfj/sYavV4oCVaXo1+GGr1SiSynwZtlr7DphPw1bru0gqq/KxT8NWa1skxYft0bNhq7Wepl4OW62Jb09bUFBQUFBQUFBQUFBQUNBO/wE/I5YvY9IQbQAAAABJRU5ErkJggg==" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a>Visual Studio je v nové verzi 2015 zase o kousek dokonalejší než předchozí verze. Ale samozřejmě není naprosto dokonalé a tak při své práci pořád používám nějaká rozšíření. Pokud možno bezplatné - šetří se všude a tak koupě licence nějakého ryze komerčního produktu často není možná. Takže tady je seznam deseti rozšíření, která mám nainstalována.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<a name='more'></a><br />
<h4>
<span style="color: red;">1. Productivity Power Tools 2015</span></h4>
<div style="text-align: justify;">
Asi je zbytečné představovat, prostě nepostradatelný pomocník. Mimo export kódu jako html do schránky - což jsem popsal <a href="http://martinstrimpfl.blogspot.cz/2016/01/nastaveni-sluzby-blogger-cili-blogspot.html">tady </a>- toho umí daleko více - například si přenastavit umístnění záložek v UI nebo si nastavit pomocné čáry v editoru, aby kód zbytečně nepřetékal do šířky. </div>
<br />
<h4>
<span style="color: red;">2. Style Cop</span></h4>
<div style="text-align: justify;">
Ve firmě není nutné sepisovat pravidla pro psaní kódu, stačí se jen řídit pokyny tohoto mocného nástroje. Existuje už pěkně dlouho a spolu s Code Analysis přispívá k psaní dobrého kódu. O těchto pomocnících jsem psal už v příspěvku <a href="http://blog.vyvojar.cz/mstr/archive/2008/11/29/policist-o-pom-haj-a-chr-n.aspx">Policisté co pomáhají a chrání </a>v roce 2008.</div>
<br />
<h4>
<span style="color: red;">3. Code Maid</span></h4>
<div style="text-align: justify;">
Rychlý úklid kódu, vyčištění zdrojáku. Přeorganizuje třídu dle pravidel, například napřed definice fieldů, konstruktory, metody a podobně. Během chvilky je zdrojový kód dle pravidel.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi0TUA3PljX0NyTQddMKYNCRNSHRsdRQ2pGh_8azEQIG7JTGQRYVRmtift17P1prnSHHBCCWlPMtKSjrZn7ikT3TSdON_vK5VzglbYpiwETFdgPnWkkjhnD3o3XnjCEkHsDxZWuoMIk28/s1600/CodeMaid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi0TUA3PljX0NyTQddMKYNCRNSHRsdRQ2pGh_8azEQIG7JTGQRYVRmtift17P1prnSHHBCCWlPMtKSjrZn7ikT3TSdON_vK5VzglbYpiwETFdgPnWkkjhnD3o3XnjCEkHsDxZWuoMIk28/s320/CodeMaid.png" width="260" /></a></div>
a tak lze z tohoto:<br />
<div>
<br /></div>
<pre><code> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">UglyClass</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">DoSomething</span><span class="punctuation">()</span>
<span class="punctuation">{</span> <span class="punctuation">}</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">counter</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">Counter</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">counter</span><span class="punctuation">;}</span> <span class="keyword" style="color: blue;">set</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">counter</span> <span class="operator">=</span> <span class="identifier - keyword - (TRANSIENT)" style="color: blue;">value</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="identifier">UglyClass</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">int</span> <span class="identifier">counter</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">counter</span> <span class="operator">=</span> <span class="identifier">counter</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">string</span> <span class="identifier">myName</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">string</span> <span class="identifier">Name</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span><span class="punctuation">;</span> <span class="keyword" style="color: blue;">set</span><span class="punctuation">;</span> <span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<div>
udělat toto:</div>
<div>
<pre><code><span class="keyword" style="color: blue;">internal</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">UglyClass</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">counter</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">string</span> <span class="identifier">myName</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">public</span> <span class="identifier">UglyClass</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">int</span> <span class="identifier">counter</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">counter</span> <span class="operator">=</span> <span class="identifier">counter</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">Counter</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">counter</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="keyword" style="color: blue;">set</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">counter</span> <span class="operator">=</span> <span class="identifier - keyword - (TRANSIENT)" style="color: blue;">value</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">string</span> <span class="identifier">Name</span> <span class="punctuation">{</span> <span class="keyword" style="color: blue;">get</span><span class="punctuation">;</span> <span class="keyword" style="color: blue;">set</span><span class="punctuation">;</span> <span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">void</span> <span class="identifier">DoSomething</span><span class="punctuation">()</span>
<span class="punctuation">{</span> <span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<br />
<br />
<h4>
<span style="color: red;">4. Visual Studio Spell Checker</span></h4>
<div>
<div style="text-align: justify;">
Nikdo nedělá rád zbytečné chyby a pokud pracujete ve firmě, kde se komentáře v kódu píši anglicky, je tohle téměř nezbytná pomůcka. Upozorní na zbytečné překlepy a nabídne jejich rychlou opravu.</div>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBywR3u6_aAGq8Hef5m467prrRbKWU4jUHYabCAqUF50Ctg8mOfjGZgnCFrOGpKlLhGvFf-Bg3DFS4UPndtD-HMo5jjYY7sbIzRkHZj3NvoasioJdDb6GEisKi9k7V2x8Nv07WUk_isPo/s1600/Spell.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="313" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBywR3u6_aAGq8Hef5m467prrRbKWU4jUHYabCAqUF50Ctg8mOfjGZgnCFrOGpKlLhGvFf-Bg3DFS4UPndtD-HMo5jjYY7sbIzRkHZj3NvoasioJdDb6GEisKi9k7V2x8Nv07WUk_isPo/s320/Spell.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
<h4>
<span style="color: red;">5. Microsoft Code Lens Code Health Indicator</span></h4>
<div style="text-align: justify;">
Přímo zpřístupní základní metriky kódu - a hned je vidět, kde je potřeba přidat co se týče komplexnosti kódu :-)</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCDcBMlLOXbT7rhS9gMHmROZ31DevxKV-ldX-i1LmbX__MK9yZq-j7nQLmJPlk-U-50p83eBIhTgTYrz4xR9AwmKjhuj4-5biOgDDqGxsBZATjlZ8_1SoOxilhaBN7uzfYT4fw88lblOQ/s1600/CodeLens.png" imageanchor="1"><img border="0" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCDcBMlLOXbT7rhS9gMHmROZ31DevxKV-ldX-i1LmbX__MK9yZq-j7nQLmJPlk-U-50p83eBIhTgTYrz4xR9AwmKjhuj4-5biOgDDqGxsBZATjlZ8_1SoOxilhaBN7uzfYT4fw88lblOQ/s640/CodeLens.png" width="640" /></a><br />
<h3>
</h3>
<h4>
<span style="color: red;"><br /></span></h4>
<h4>
<span style="color: red;">6. VS Color Output</span></h4>
Output okénko se pěkne zabarví a tak se v něm snadněji orientuje.<br />
<br /></div>
<div>
<h4>
<span style="color: red;">7. Move Type To File</span></h4>
<div style="text-align: justify;">
Pokud máte v jednom souboru více definic tříd, stačí klepnutí a definice se přesune do vlastního souboru, pojmenovaného dle názvu třídy. </div>
<br />
<h4>
<span style="color: red;">8. Comments Plus</span></h4>
Komentáře kurzivou a umožňující jednoduché formátování pomocí značek:<br />
<br /></div>
<div>
<pre><code><span class="comment" style="color: green; font-style: italic;">// Special handling for quoted field</span>
<span class="comment" style="color: green; font-style: italic;">//! <b>be very careful when changing it</b></span>
<span class="comment" style="color: green; font-style: italic;"><span style="color: green; font-style: italic;">//x </span><strike><span style="color: #666666;">some old comment</span></strike></span>
<span class="comment" style="color: green; font-style: italic;">//TODO: </span><span class="comment" style="color: #e69138; font-style: italic;">s</span><span class="comment" style="color: #b45f06; font-style: italic;">pecial task to finish</span>
<span class="comment" style="color: green; font-style: italic;">//!? </span><span class="comment" style="color: magenta; font-style: italic;">what does it mean</span></code></pre>
<br />
<h4>
<span style="color: red;">9. RazorEngine.Generator</span></h4>
</div>
<div>
Aneb využití razoru i mimo web aplikace. Více jsem se rozepsal v samostatném příspěvku <a href="http://martinstrimpfl.blogspot.cz/2014/12/vyuziti-razor-mimo-web.html">Využítí Razor mimo web</a> na konci roku 2014.<br />
<h4>
<span style="color: red;"><br />10. File Nesting</span></h4>
Ve VS 2013 a níže jsem používal VS Commands, ale ty pod VS 2015 nějak nefungují. Takže pro zanoření souborů pod sebe teď používám toto rozšíření.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6y7oLKeug4BmUCdWA1UivOnsmrqehfTGFbjl3Dfo4xPxOFviZiCW2e6R_m6NLqTNF0HELI0Kh5s_74eWpABVKNyR7b5GF2-DUNT2PmQiZvfdwNRmZ7aDpd4EiCIeIyHQhxjrIdnXryt0/s1600/Nest.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6y7oLKeug4BmUCdWA1UivOnsmrqehfTGFbjl3Dfo4xPxOFviZiCW2e6R_m6NLqTNF0HELI0Kh5s_74eWpABVKNyR7b5GF2-DUNT2PmQiZvfdwNRmZ7aDpd4EiCIeIyHQhxjrIdnXryt0/s400/Nest.JPG" /></a></div>
<br /></div>
</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-2788711653865750332016-01-28T05:25:00.000+01:002016-01-28T07:18:29.136+01:00Hrátky s Linqem aneb Distinct pětkrát jinak<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7CxKCUhKKoEiVljk5M4tFYFittIsyQVs7P7EGPkR6TePkZ-qRroRpFXPTmmMm370D1SUo-PZefUmmu1B28FeB5Jkkxh-xUcqiPI7HYplO7H21X8JT3gXT1m7Te9Nav76-SwG5Wm-9sFg/s1600/LinqLogo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7CxKCUhKKoEiVljk5M4tFYFittIsyQVs7P7EGPkR6TePkZ-qRroRpFXPTmmMm370D1SUo-PZefUmmu1B28FeB5Jkkxh-xUcqiPI7HYplO7H21X8JT3gXT1m7Te9Nav76-SwG5Wm-9sFg/s200/LinqLogo.png" width="200" /></a><br />
<div style="text-align: justify;">
Dotazovací jazyk LINQ není asi nutné nějak detailněji představovat - je součástí .NETu už pěkně dlouho. Použití našel nejen jako součást Entity Frameworku, kde umožňuje přístup k datům v databázi i bez znalosti SQL, ale prakticky všude, kde je potřeba zpracovávat kolekce. </div>
<span style="text-align: justify;">Jak se píše na české Wikipedii, "</span><i style="text-align: justify;">LINQ přináší nový způsob pro dotazování nad jakýmikoliv daty, usnadňuje jejich tvorbu, třídění, jejich propojování i vyhledávání v nich.... je možné v něm manipulovat s různými daty.</i><span style="text-align: justify;">"</span><br />
<a name='more'></a><div style="text-align: justify;">
Jedním z častých úkolů je odstranit v dané kolekci duplicity. To je jednoduché pro kolekce hodnot, stačí použít operátor <b>Distinct </b>a duplicitní položky jsou odstraněny:</div>
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">numbers</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="keyword" style="color: blue;">int</span><span class="punctuation">[]</span> <span class="punctuation">{</span> <span class="number">1</span><span class="punctuation">,</span> <span class="number">2</span><span class="punctuation">,</span> <span class="number">3</span><span class="punctuation">,</span> <span class="number">1</span><span class="punctuation">,</span> <span class="number">2</span><span class="punctuation">,</span> <span class="number">3</span><span class="punctuation">,</span> <span class="number">4</span><span class="punctuation">,</span> <span class="number">5</span> <span class="punctuation">};</span>
<span class="keyword" style="color: blue;">var</span> <span class="identifier">cleanedNumbers</span> <span class="operator">=</span> <span class="identifier">numbers</span><span class="operator">.</span><span class="identifier">Distinct</span><span class="punctuation">();</span></code></pre>
<div style="text-align: justify;">
<!-- END -->
Jakmile je kolekce tvořena objekty, je úkol obtížnější. Existuje třeba kolekce autorů, kde se ale někteří autoři vyskytují díky nějaké chybě dvakrát. Cílem je mít kolekci bez duplicit, tedy kolekci, ve které se každý autor vyskytuje jen jednou.</div>
<!-- START --><br />
<pre><code> <span class="keyword" style="color: blue;">var</span> <span class="identifier">authors</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span><span class="punctuation">[]</span> <span class="punctuation">{</span>
<span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="punctuation">{</span> <span class="identifier">FirstName</span> <span class="operator">=</span><span class="string" style="color: #a31515;">"Joseph"</span><span class="punctuation">,</span> <span class="identifier">Surname</span><span class="operator">=</span><span class="string" style="color: #a31515;">"Albahari"</span> <span class="punctuation">},</span>
<span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="punctuation">{</span> <span class="identifier">FirstName</span> <span class="operator">=</span><span class="string" style="color: #a31515;">"Ben"</span><span class="punctuation">,</span> <span class="identifier">Surname</span> <span class="operator">=</span><span class="string" style="color: #a31515;">"Albahari"</span> <span class="punctuation">},</span>
<span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="punctuation">{</span> <span class="identifier">FirstName</span> <span class="operator">=</span> <span class="string" style="color: #a31515;">"Andrew"</span><span class="punctuation">,</span> <span class="identifier">Surname</span> <span class="operator">=</span> <span class="string" style="color: #a31515;">"Troelsen"</span> <span class="punctuation">},</span>
<span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="punctuation">{</span> <span class="identifier">FirstName</span> <span class="operator">=</span><span class="string" style="color: #a31515;">"Joseph"</span><span class="punctuation">,</span> <span class="identifier">Surname</span><span class="operator">=</span><span class="string" style="color: #a31515;">"Albahari"</span> <span class="punctuation">},</span>
<span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="punctuation">{</span> <span class="identifier">FirstName</span> <span class="operator">=</span><span class="string" style="color: #a31515;">"Ben"</span><span class="punctuation">,</span> <span class="identifier">Surname</span> <span class="operator">=</span><span class="string" style="color: #a31515;">"Albahari"</span> <span class="punctuation">},</span>
<span class="punctuation">};</span></code></pre>
<!-- END -->
<br />
Nabízí se několik možností:<br />
<br />
<h3>
1. Upravit třídu</h3>
<div style="text-align: justify;">
To většinou není ani vhodné a nebo ani možné. Bylo by nutné přepsat metodu <b>Equals</b> dané třídy a metody generující hash code. A tomu bych se raději vyhnul - existuje více důvodů, proč to nedělat a v praxi se mi to většinou vymstilo. Takže to tady ani raději nebudu doprovázet ukázkou kódu.</div>
<br />
<h3>
2. Použít vlastní porovnávač - třídu implementující IEqualityComparer<T></h3>
Pokud nám nevadí napsat si vlastní třídu, která implementuje rozhraní IEqulaityCompararer, tak to lze udělat tak, že si nejpreve napíšeme vlastní porovnávač:<br />
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">AuthorComparer</span> <span class="punctuation">:</span> <span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">IEqualityComparer</span><span class="punctuation"><</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span><span class="punctuation">></span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">bool</span> <span class="identifier">Equals</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="identifier">x</span><span class="punctuation">,</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="identifier">y</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span>
<span class="identifier">x</span><span class="operator">.</span><span class="identifier">FirstName</span><span class="operator">.</span><span class="identifier">Equals</span><span class="punctuation">(</span><span class="identifier">y</span><span class="operator">.</span><span class="identifier">FirstName</span><span class="punctuation">)</span>
<span class="operator">&&</span>
<span class="identifier">x</span><span class="operator">.</span><span class="identifier">Surname</span><span class="operator">.</span><span class="identifier">Equals</span><span class="punctuation">(</span><span class="identifier">y</span><span class="operator">.</span><span class="identifier">Surname</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">GetHashCode</span><span class="punctuation">(</span><span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="identifier">obj</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">unchecked</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">int</span> <span class="identifier">hash</span> <span class="operator">=</span> <span class="number">17</span><span class="punctuation">;</span>
<span class="identifier">hash</span> <span class="operator">=</span> <span class="identifier">hash</span> <span class="operator">*</span> <span class="number">23</span> <span class="operator">+</span> <span class="identifier">obj</span><span class="operator">.</span><span class="identifier">FirstName</span><span class="operator">.</span><span class="identifier">GetHashCode</span><span class="punctuation">();</span>
<span class="identifier">hash</span> <span class="operator">=</span> <span class="identifier">hash</span> <span class="operator">*</span> <span class="number">23</span> <span class="operator">+</span> <span class="identifier">obj</span><span class="operator">.</span><span class="identifier">Surname</span><span class="operator">.</span><span class="identifier">GetHashCode</span><span class="punctuation">();</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">hash</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
A pak ho použijeme:<br />
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">cleanedAuthors</span> <span class="operator">=</span> <span class="identifier">authors</span><span class="operator">.</span><span class="identifier">Distinct</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">AuthorComparer</span><span class="punctuation">());</span></code></pre>
<div style="text-align: justify;">
<!-- END -->
Nevýhodou je nepřehlednost kódu, pro zjištění, na základě čeho se zjišťují duplicity, je nutné přejít do třídy <b>AuthorCompare</b>. Navíc je nutné podobnou třídu vytvořit pro každou třídu, respektive kolekci, kterou chceme vytřídit.</div>
<br />
<h3>
3. Anonymní typ</h3>
<div style="text-align: justify;">
Anonymní typ je definován jako bezejmenná třída. Pro vytvoření stačí v inicialitoru určit názvy vlastností a jejich hodnoty - vlastnosti budou nadále jen read only. Anonymní typ je potomkem třídy <b>System.Object</b>.</div>
<div style="text-align: justify;">
Důležitou vlastností je, že při porovnání anonymního typu probíhá porovnání na základě hodnot všech veřejných vlastností. Stačí tedy vygenerovat kolekci anonymních typů:</div>
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">cleanedAuthors</span> <span class="operator">=</span> <span class="identifier">authors</span>
<span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">a</span> <span class="operator">=></span> <span class="keyword" style="color: blue;">new</span> <span class="punctuation">{</span> <span class="identifier">FirstName</span> <span class="operator">=</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">FirstName</span><span class="punctuation">,</span> <span class="identifier">Surname</span> <span class="operator">=</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">Surname</span> <span class="punctuation">})</span>
<span class="operator">.</span><span class="identifier">Distinct</span><span class="punctuation">();</span></code></pre>
<!-- END -->
<br />
<br />
<div style="text-align: justify;">
Nevýhodou ovšem je, že dostaneme kolekci anonymních typů. To nutně nemusí být na závadu, pokud nám stačí dále pracovat jen s vlastnostmi bez ohledu na typ, ale pokud chceme mít kolekci autorů, je nutné mít volání složitější:</div>
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">cleanAuthors</span> <span class="operator">=</span> <span class="identifier">authors</span>
<span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">a</span> <span class="operator">=></span> <span class="keyword" style="color: blue;">new</span> <span class="punctuation">{</span> <span class="identifier">FirstName</span> <span class="operator">=</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">FirstName</span><span class="punctuation">,</span> <span class="identifier">Surname</span> <span class="operator">=</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">Surname</span> <span class="punctuation">})</span><span class="operator">.</span><span class="identifier">Distinct</span><span class="punctuation">()</span>
<span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">a</span> <span class="operator">=></span> <span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">Author</span> <span class="punctuation">{</span> <span class="identifier">FirstName</span> <span class="operator">=</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">FirstName</span><span class="punctuation">,</span> <span class="identifier">Surname</span> <span class="operator">=</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">Surname</span> <span class="punctuation">});</span></code></pre>
<!-- END -->
<br />
<h3>
4. Seskupení</h3>
<div>
Můžeme také využít seskupení a vybrat první element z každé skupiny:</div>
<div>
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">cleanAuthors</span> <span class="operator">=</span> <span class="identifier">authors</span>
<span class="operator">.</span><span class="identifier">GroupBy</span><span class="punctuation">(</span><span class="identifier">a</span> <span class="operator">=></span> <span class="keyword" style="color: blue;">new</span> <span class="punctuation">{</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">FirstName</span><span class="punctuation">,</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">Surname</span> <span class="punctuation">})</span>
<span class="operator">.</span><span class="identifier">Select</span><span class="punctuation">(</span><span class="identifier">g</span> <span class="operator">=></span> <span class="identifier">g</span><span class="operator">.</span><span class="identifier">First</span><span class="punctuation">());</span></code></pre>
<!-- END -->
</div>
<div>
<br />
<div style="text-align: justify;">
Určitou nevýhodu tohoto postupu může být mírná nepřehlednost, kdy se za použitím GroupBy operátor vlastně skrývá operace Distinct a v budoucnu to může vést k nepřehlednosti a obtížnému chápání takového kódu. Dobré je tedy doplnit do kódu poznámku o co vlasně ve skutečnosti jde.<br />
<br />
<h3>
5. Zkombinovat 2 a 3</h3>
</div>
</div>
A co zkusit výhody, které by nám nabídla kombinace rozšiřujících metod, anonymního typu, predikátu a vlastního porovnávače. Nejprve je nutné implementovat třídu implementující IEqualityComparer rozhraní:<br />
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">ByKeyComparer</span><span class="punctuation"><</span><span class="type parameter name" style="color: #2b91af;">T</span><span class="punctuation">></span> <span class="punctuation">:</span> <span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">IEqualityComparer</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">></span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">private</span> <span class="keyword" style="color: blue;">readonly</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">object</span><span class="punctuation">></span> <span class="identifier">keySelector</span><span class="punctuation">;</span>
<span class="keyword" style="color: blue;">public</span> <span class="identifier">ByKeyComparer</span><span class="punctuation">(</span><span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">object</span><span class="punctuation">></span> <span class="identifier">keySelector</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">keySelector</span> <span class="operator">=</span> <span class="identifier">keySelector</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">bool</span> <span class="identifier">Equals</span><span class="punctuation">(</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span> <span class="identifier">x</span><span class="punctuation">,</span> <span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span> <span class="identifier">y</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">keySelector</span><span class="punctuation">(</span><span class="identifier">x</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">Equals</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">keySelector</span><span class="punctuation">(</span><span class="identifier">y</span><span class="punctuation">));</span>
<span class="punctuation">}</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">int</span> <span class="identifier">GetHashCode</span><span class="punctuation">(</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span> <span class="identifier">obj</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">this</span><span class="operator">.</span><span class="identifier">keySelector</span><span class="punctuation">(</span><span class="identifier">obj</span><span class="punctuation">)</span><span class="operator">.</span><span class="identifier">GetHashCode</span><span class="punctuation">();</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
Poté napsat extension metodu pro Linq:<br />
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="keyword" style="color: blue;">class</span> <span class="class name" style="color: #2b91af;">LinqExtension</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">public</span> <span class="keyword" style="color: blue;">static</span> <span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">IEnumerable</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">></span> <span class="identifier">Distinct</span><span class="punctuation"><</span><span class="type parameter name" style="color: #2b91af;">T</span><span class="punctuation">>(</span><span class="keyword" style="color: blue;">this</span> <span class="identifier - interface name - (TRANSIENT)" style="color: #2b91af;">IEnumerable</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">></span> <span class="identifier">input</span><span class="punctuation">,</span> <span class="delegate name - identifier - (TRANSIENT)" style="color: #2b91af;">Func</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">,</span> <span class="keyword" style="color: blue;">object</span><span class="punctuation">></span> <span class="identifier">keySelector</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
<span class="keyword" style="color: blue;">return</span> <span class="identifier">input</span><span class="operator">.</span><span class="identifier">Distinct</span><span class="punctuation">(</span><span class="keyword" style="color: blue;">new</span> <span class="class name - identifier - (TRANSIENT)" style="color: #2b91af;">ByKeyComparer</span><span class="punctuation"><</span><span class="identifier - type parameter name - (TRANSIENT)" style="color: #2b91af;">T</span><span class="punctuation">>(</span><span class="identifier">keySelector</span><span class="punctuation">));</span>
<span class="punctuation">}</span>
<span class="punctuation">}</span></code></pre>
<!-- END -->
A nyní je při zápisu příkazu dostupná další implementaci volání <b>Distinct</b>:<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmx7jBhUGSx1ebno5965Pa0o9QPHUTHAOMFl_Y-H_GLLPHBA0NN1cV1m8tavFTWucKqRxocUq9esyDYSYvKL81DcYMxJn7mF_PDaohyphenhyphen8fzYnhvuFY0wUufVW9nxXUHmXeDqHGJld2o-Z0/s1600/LinqDistinct.JPG" imageanchor="1"><img border="0" height="57" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmx7jBhUGSx1ebno5965Pa0o9QPHUTHAOMFl_Y-H_GLLPHBA0NN1cV1m8tavFTWucKqRxocUq9esyDYSYvKL81DcYMxJn7mF_PDaohyphenhyphen8fzYnhvuFY0wUufVW9nxXUHmXeDqHGJld2o-Z0/s640/LinqDistinct.JPG" width="640" /></a><br />
<div style="text-align: justify;">
Jenže pokud zadáme jen jednu vlastnost, tedy přijmení, nebude výsledný seznam autorů přesný - pokud by kolekce obsahovala autory<b><i> Joseph Albahari</i></b> a <b><i>Ben Albahari</i></b>, tak se nám ve výsledku objeví jen jeden z nich v závislosti na svém pořadí v kolekci. Což je špatně. A tak nyní přichází na řadu anonymní typ, stačí totiž zapsat toto:</div>
<!-- START --><br />
<pre><code><span class="keyword" style="color: blue;">var</span> <span class="identifier">cleanedAuthors</span> <span class="operator">=</span> <span class="identifier">authors</span><span class="operator">.</span><span class="identifier">Distinct</span><span class="punctuation">(</span><span class="identifier">a</span> <span class="operator">=></span> <span class="keyword" style="color: blue;">new</span> <span class="punctuation">{</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">FirstName</span><span class="punctuation">,</span> <span class="identifier">a</span><span class="operator">.</span><span class="identifier">Surname</span> <span class="punctuation">});</span></code></pre>
<!-- END -->
a díky vlastnostem anonymního typu (viz výše) a implementaci třídy <b>ByKeyComparer </b>dojde k porovnávání těchto dvou vlastností nové anonymní třídy.<br />
<br />
Možná existují další metody, ale výše uvedené jsou ty, které používám já.<br />
<br />
Spustitelný kód je dostupný na <a href="https://dotnetfiddle.net/Eoziu7">.NET Fiddle</a>:<br />
<iframe frameborder="0" height="400" src="https://dotnetfiddle.net/Widget?Languages=CSharp&CSharp_FiddleId=fdqMCr" width="100%"></iframe>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-43150921150298897782016-01-27T15:39:00.001+01:002016-01-27T15:39:09.691+01:00Záznamy přednášek na NDC London 2016<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3LYIaaLn4ctrRdzh12aRsMIISrHjcr1UqVIoz9Lsl4WPTAqGX_wDNApiNhZtstMJX0Ft9_Fq7y1Ha5l9kqnXcagotdrgHlL6t-_2__6Vfy_gZPjQe2mFPPFuD0t-nvKyx5goSfx_ntvI/s1600/sta%25C5%25BEen%25C3%25BD+soubor.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3LYIaaLn4ctrRdzh12aRsMIISrHjcr1UqVIoz9Lsl4WPTAqGX_wDNApiNhZtstMJX0Ft9_Fq7y1Ha5l9kqnXcagotdrgHlL6t-_2__6Vfy_gZPjQe2mFPPFuD0t-nvKyx5goSfx_ntvI/s1600/sta%25C5%25BEen%25C3%25BD+soubor.jpg" /></a><br />
<div style="text-align: justify;">
V Londýně se od 11. do 16. ledna tohoto roku konala konference <b>NDC</b> (za touto zkratkou se skrývá plný název, tj.<b> Norwegian Developers Conference</b> - myslím, že nemá cenu pátrat, proč se norská vývojářská konference koná mimo Oslo už nejen v Londýně, ale i v Sydney. Značka se dobře zavedla a proč ji nevyvážet, že :-). Tyhle konference začalil v roce 2008 a troufám si tvrdit, že překonali kdysi oblíbený TechEd. </div>
<div style="text-align: justify;">
<a name='more'></a>Účast na nich stojí víceméně stejně. A pro ty, kteří šetří a nebo na zaplacení účastnického poplatku nemají, jsou tady bezplatné záznamy přednášek. Tento týden začali organizátoři uvolňovat nahrávky, lze je nalézt na <a href="https://vimeo.com/ndcconferences">https://vimeo.com/ndcconferences</a>.</div>
<div style="text-align: justify;">
<br /></div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com5tag:blogger.com,1999:blog-2993762679677061763.post-356483287685398812016-01-22T07:17:00.000+01:002016-01-24T13:48:10.459+01:00Tisk příspěvku na Blogspot a kopírování kódu z Visual Studia jako HTML<div style="text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8bOgliSZxUvji-mClvx5g1ZyNCIDiowq1wgu1JCtYOcSEU7zgG1JZ05VRuCaHvfi7o-YSNb8S23kAAQjDUnCBcRszl1d2AyTDeFvffzPMl-THTV7n26OTPiYXt9DLwVipdfFHIGxuq2g/s1600/logo.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="54" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8bOgliSZxUvji-mClvx5g1ZyNCIDiowq1wgu1JCtYOcSEU7zgG1JZ05VRuCaHvfi7o-YSNb8S23kAAQjDUnCBcRszl1d2AyTDeFvffzPMl-THTV7n26OTPiYXt9DLwVipdfFHIGxuq2g/s200/logo.JPG" width="200" /></a>První blog jsem si kdysi založil na vývojaři a pořád ho tam ještě mám - <a href="http://blog.vyvojar.cz/mstr/">http://blog.vyvojar.cz/mstr/</a>. Je to prakticky už jeden z posledních aktivních blogů na tomto kdysi aktivním serveru. Na svoji dobu nebyl špatný, ale nějak ustrnul, občas je nedostupný a psaní a zejména formátování příspěvků nebyla snadná práce. </div>
<a name='more'></a><br />
<div style="text-align: justify;">
V té době práci hodně usnadnil Live Writer, o kterém jsem napsal i na svém blogu <a href="http://blog.vyvojar.cz/mstr/archive/2008/07/19/ja_2C00_-live-writer-blog-a--vyvojar.aspx">http://blog.vyvojar.cz/mstr/archive/2008/07/19/ja_2C00_-live-writer-blog-a--vyvojar.aspx</a>. Ale protože mnohé další problémy zůstávali, změnil jsme nakonec službu a skončil u Google. Psaní programátorských příspěvků ale ztrpčovalo vkládání kódu - jak to udělat, aby to vypadalo pěkně. Nakonec jsem k nějakému řešení dospěl a tady je stručný postup</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Kopírování kódu Visual Studia jako html</h3>
<div style="text-align: justify;">
Je nutné si nainstalovat doplněk <b>Productivity Power Tools</b>. Instalace je jednoduchá, stačí vyvolat okno <b>Extension and Updates</b> přes nabídku <b>Tools</b> > <b>Extension and updates</b>.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKkmMD1IyrOawBC6eR9om90VMsIbnKdDOstEz-Sdjna4ldGHNRCx_mGiAhZEp4WgpgXbj2lZcCRot-0-p50t_Sqyd9DclbD1vRQ1_yn3JENDisYBfnDesOKtKOSGLB4TRe6HJLG2euhKs/s1600/ExtenUpdWIn.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKkmMD1IyrOawBC6eR9om90VMsIbnKdDOstEz-Sdjna4ldGHNRCx_mGiAhZEp4WgpgXbj2lZcCRot-0-p50t_Sqyd9DclbD1vRQ1_yn3JENDisYBfnDesOKtKOSGLB4TRe6HJLG2euhKs/s400/ExtenUpdWIn.JPG" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Poté se musí doplněk vyhledat, nainstalovat a následuje restart Visual Studia.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Po restartu v okně <b>Options</b> (<b>Tools</b> > <b>Options</b>) vyhledáme položku <b>Productivity Power Tools</b> a podpoložku <b>HTML Copy </b>a nastavíme ji takto:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhehsDtRsA38ARgaFyx5YJkUeHhWssOm2umhgsrlAgFLFh0C6REFTZZUxI2nR6lfp7P84WrAfr6rw9oGpJcVTWXrhzuLER2AkLEucZtLZIL5YUGUNHAqt7i6-9qAkC_Yq7htCIUuFgj5Rg/s1600/OptionsWin.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhehsDtRsA38ARgaFyx5YJkUeHhWssOm2umhgsrlAgFLFh0C6REFTZZUxI2nR6lfp7P84WrAfr6rw9oGpJcVTWXrhzuLER2AkLEucZtLZIL5YUGUNHAqt7i6-9qAkC_Yq7htCIUuFgj5Rg/s400/OptionsWin.JPG" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Poznámka: klíč <b>EmitSpanStyle</b> může být nastaven na <b>False</b>, ale nastavením na <b>True</b> se zajistí správné barevné kopírování kódu i do jiných cílových destinací, než je blog. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Tím je nastavení Visual Studia hotové. Nyní stačí označit kód, který se ma kopírovat a z nabídky <b>Edit </b>zvolit nový příkaz <b>Copy Html Markup</b>:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwM1X7YF7j4h5kMuBoj8dXcSkLK2Qpcr0Z5YAsrsGiC6ySjPAenSfMHbxsekFseMDdOTMz2r1WzOSAdWXFj1v4ev5F1zuiz52PCmy6l_EtqvD2vSgHbLLdwRBhe4At3d2f1UUYjdcHJRo/s1600/NewCommand.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwM1X7YF7j4h5kMuBoj8dXcSkLK2Qpcr0Z5YAsrsGiC6ySjPAenSfMHbxsekFseMDdOTMz2r1WzOSAdWXFj1v4ev5F1zuiz52PCmy6l_EtqvD2vSgHbLLdwRBhe4At3d2f1UUYjdcHJRo/s320/NewCommand.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h3 style="text-align: justify;">
Nastavení šablony na blogu:</h3>
<div style="text-align: justify;">
Aby se zkopírovaný kód na stránkách blogu dobře vykreslil, je nutné si přidat vlastní styly. Jde to takto:<br />
<br /></div>
<div style="text-align: justify;">
V administraci blogu vybereme sekci <b>Šablona</b> poté a klikneme na tlačítko <b>Personalizovat</b>:<br />
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA7GEukbBHVoi1D4IIqT_y7yzSncdMJe4cfuf5nd8Z3STKROLT_UpiAnFpUAnqVvTkbA_Sj5N8V-fH9fBHn9rXfxnLE2Zs_pCriZtbvXtkxN1UfDb-RjBcIaD04XLpUJS4kE6ixJnrXeY/s1600/Template.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA7GEukbBHVoi1D4IIqT_y7yzSncdMJe4cfuf5nd8Z3STKROLT_UpiAnFpUAnqVvTkbA_Sj5N8V-fH9fBHn9rXfxnLE2Zs_pCriZtbvXtkxN1UfDb-RjBcIaD04XLpUJS4kE6ixJnrXeY/s400/Template.JPG" width="400" /></a></div>
<br />
Poté zvolíme <b>Pokročilé </b> a z rolovacího seznamu vybereme <b>Přidat CSS</b>:<br />
<b><br /></b></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqtjQzxVoROW1whFJPT7XwJMwWIwDdLSi0aDco4qv6H_fM-6op2ipSLRLrpOA0GBFM0zBpETignZqko_H0vqYpxCKVFkHwOkm8XR4Jp06R0PImoCzn5A2n52k28G6vylJXNvkqPerB7aY/s1600/Template2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqtjQzxVoROW1whFJPT7XwJMwWIwDdLSi0aDco4qv6H_fM-6op2ipSLRLrpOA0GBFM0zBpETignZqko_H0vqYpxCKVFkHwOkm8XR4Jp06R0PImoCzn5A2n52k28G6vylJXNvkqPerB7aY/s400/Template2.JPG" width="400" /></a></div>
<br />
<br />
Do příslušného okénka vložíme tento CSS kód:</div>
<div style="text-align: justify;">
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007700;">pre</span>
{
<span style="color: #008800; font-weight: bold;">font-family</span><span style="color: #333333;">:</span> Andale Mono<span style="color: #333333;">,</span> Lucida Console<span style="color: #333333;">,</span> Monaco<span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">fixed</span><span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">monospace</span>;
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#000000</span>;
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#eee</span>;
<span style="color: #008800; font-weight: bold;">font-size</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">12px</span>;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">1px</span> <span style="color: #008800; font-weight: bold;">dashed</span> <span style="color: #6600ee; font-weight: bold;">#999999</span>;
<span style="color: #008800; font-weight: bold;">line-height</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">13px</span>;
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">15px</span>;
<span style="color: #008800; font-weight: bold;">overflow</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">auto</span>;
<span style="color: #008800; font-weight: bold;">max-width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">95</span><span style="color: #333333;">%</span>;
<span style="color: #008800; font-weight: bold;">max-height</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">300px</span>;
}
<span style="color: #007700;">pre</span> <span style="color: #007700;">code</span> {
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#000000</span>;
word<span style="color: #333333;">-</span>wrap<span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">normal</span>;
}
<span style="color: #007700;">pre</span> <span style="color: #007700;">code</span> <span style="color: #bb0066; font-weight: bold;">.keyword</span> {
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #007020;">blue</span>;
}
<span style="color: #007700;">pre</span> <span style="color: #007700;">code</span> <span style="color: #bb0066; font-weight: bold;">.identifier</span> {
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#333</span><span style="color: #557799;">!important</span>;
<span style="color: #008800; font-weight: bold;">font-weight</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">bolder</span>;
}
<span style="color: #007700;">pre</span> <span style="color: #007700;">code</span> <span style="color: #bb0066; font-weight: bold;">.operator</span> {
}
<span style="color: #007700;">pre</span> <span style="color: #007700;">code</span> <span style="color: #bb0066; font-weight: bold;">.User.Types</span> {
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #007020;">blue</span>;
}
<span style="color: #007700;">pre</span> <span style="color: #007700;">code</span> <span style="color: #bb0066; font-weight: bold;">.string</span> {
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#a31515</span><span style="color: #557799;">!important</span>;
<span style="color: #008800; font-weight: bold;">font-weight</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">bolder</span>;
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#E8FF11</span>;
}
</pre>
</div>
<br />
Ten zajistí, aby se vložený kod obarvil jednotným způsobem a zároveň aby se na obrazovku vykreslil odděleně a v případě, že přesáhne výška 300 px, aby se objevily rolovací lišty.<br />
<br />
Výsledek na stránce vypadá takto:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqxwYmpGPcfRlPegSSRUsx-DFsD8Dw8Y77tpujFpS9MgkSqw9l-XTcVFzJvWPp83tNDm5_8FBbJTm7Js8euzOsRSyIpxrtVS60OtB9OZpqXId3Vj794kJtAGtEQG7FTIHIbpeSVqTKZFQ/s1600/Result.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqxwYmpGPcfRlPegSSRUsx-DFsD8Dw8Y77tpujFpS9MgkSqw9l-XTcVFzJvWPp83tNDm5_8FBbJTm7Js8euzOsRSyIpxrtVS60OtB9OZpqXId3Vj794kJtAGtEQG7FTIHIbpeSVqTKZFQ/s640/Result.JPG" width="640" /></a></div>
<br /></div>
<div style="text-align: justify;">
<h3>
Tisk příspěvku</h3>
Pokud si někdo chce vytisknou příspěvek, není výsledek příliš pěkný. Ve výchozím nastavení se tiskne i boční panel blogu a spousta se článkem nesouvisejícího balastu. Řešením je přidat vlastní styl pro tisk. Postup je stejný jako při vkládání vlastních stylů podle popisu v předchozí stati, je ale potřeba přidat k již stávajícím stylům toto:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">@media</span> <span style="color: #007700;">print</span> {
<span style="color: #007700;">pre</span> {
<span style="color: #008800; font-weight: bold;">font-family</span><span style="color: #333333;">:</span> Andale Mono<span style="color: #333333;">,</span> Lucida Console<span style="color: #333333;">,</span> Monaco<span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">fixed</span><span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">monospace</span>;
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#000000</span>;
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #007020;">white</span><span style="color: #557799;">!important</span>;
<span style="color: #008800; font-weight: bold;">font-size</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">12px</span>;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">1px</span> <span style="color: #008800; font-weight: bold;">dashed</span> <span style="color: #6600ee; font-weight: bold;">#999999</span>;
<span style="color: #008800; font-weight: bold;">line-height</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">13px</span>;
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">15px</span>;
<span style="color: #008800; font-weight: bold;">min-height</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span>;
<span style="color: #008800; font-weight: bold;">max-height</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
word<span style="color: #333333;">-</span>wrap<span style="color: #333333;">:</span> break<span style="color: #333333;">-</span>word;
}
<span style="color: #007700;">pre</span> <span style="color: #007700;">code</span> <span style="color: #333333;">*</span> {
<span style="color: #008800; font-weight: bold;">overflow</span><span style="color: #333333;">-</span>wrap<span style="color: #333333;">:</span> break<span style="color: #333333;">-</span>word;
}
<span style="color: #888888;">/* hide Blogger bar */</span>
<span style="color: #0066bb; font-weight: bold;">#navbar-iframe</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #888888;">/* Reset colors to black text on white background and background images */</span>
<span style="color: #bb0066; font-weight: bold;">.header</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.footer-outer</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.post-outer</span> {
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #007020;">white</span>;
<span style="color: #008800; font-weight: bold;">background-image</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #007020;">black</span>;
<span style="color: #008800; font-weight: bold;">text-shadow</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #888888;">/* Hide Pages, sidebars, embedded videos & iframes */</span>
<span style="color: #bb0066; font-weight: bold;">.tabs-outer</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.sidebar</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">%</span>;
}
<span style="color: #007700;">iframe</span><span style="color: #333333;">,</span>
<span style="color: #007700;">object</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.blog-pager</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.quickedit</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.post-feeds</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.post-share-buttons</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.comment-replybox-thread</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #888888;">/* Reset post width to fill the entire page */</span>
<span style="color: #bb0066; font-weight: bold;">.main-inner</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.columns</span> {
<span style="color: #008800; font-weight: bold;">padding-left</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0px</span> <span style="color: #557799;">!important</span>;
<span style="color: #008800; font-weight: bold;">padding-right</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0px</span> <span style="color: #557799;">!important</span>;
<span style="color: #008800; font-weight: bold;">padding-top</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">5px</span><span style="color: #557799;">!important</span>;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
}
<span style="color: #bb0066; font-weight: bold;">.content-outer</span> {
<span style="color: #008800; font-weight: bold;">margin</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0px</span>;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
}
<span style="color: #bb0066; font-weight: bold;">.content-inner</span> {
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0px</span>;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
}
<span style="color: #bb0066; font-weight: bold;">.post-outer</span> {
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
}
<span style="color: #888888;">/* Specific for my blog */</span>
<span style="color: #0066bb; font-weight: bold;">#footer-2-1</span><span style="color: #333333;">,</span>
<span style="color: #0066bb; font-weight: bold;">#footer-2-2</span><span style="color: #333333;">,</span>
<span style="color: #0066bb; font-weight: bold;">#sharenav</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.buttonlist</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.videocontainer</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.comment-form</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.header-inner</span> <span style="color: #bb0066; font-weight: bold;">.Header</span> <span style="color: #bb0066; font-weight: bold;">.descriptionwrapper</span> {
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0px</span> <span style="color: #6600ee; font-weight: bold;">30px</span>;
<span style="color: #008800; font-weight: bold;">margin</span><span style="color: #333333;">-</span>botton<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">5px</span>;
}
<span style="color: #bb0066; font-weight: bold;">.Header</span> <span style="color: #bb0066; font-weight: bold;">.description</span> {
<span style="color: #008800; font-weight: bold;">margin</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0px</span>;
<span style="color: #008800; font-weight: bold;">font-size</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
}
<span style="color: #bb0066; font-weight: bold;">.post-footer</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.comments</span> <span style="color: #bb0066; font-weight: bold;">.continue</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.comment-actions.secondary-text</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.comments</span> <span style="color: #bb0066; font-weight: bold;">.comment-thread.inline-thread</span> {
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #007020;">white</span><span style="color: #557799;">!important</span>;
}
<span style="color: #bb0066; font-weight: bold;">.comments</span> <span style="color: #bb0066; font-weight: bold;">.avatar-image-container</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.comments</span> <span style="color: #bb0066; font-weight: bold;">.comment-block</span> {
<span style="color: #008800; font-weight: bold;">margin-left</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span>;
}
<span style="color: #bb0066; font-weight: bold;">.comments</span> <span style="color: #bb0066; font-weight: bold;">.thread-toggle</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.comments</span> <span style="color: #bb0066; font-weight: bold;">.comments-content</span> <span style="color: #bb0066; font-weight: bold;">.comment</span> {
<span style="color: #008800; font-weight: bold;">margin-bottom</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">2px</span>;
<span style="color: #008800; font-weight: bold;">margin-top</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">2px</span>;
}
<span style="color: #bb0066; font-weight: bold;">.post</span> {
<span style="color: #008800; font-weight: bold;">margin-bottom</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">5px</span>;
}
<span style="color: #bb0066; font-weight: bold;">.column-center-outer</span> {
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">98</span><span style="color: #333333;">%</span>;
}
<span style="color: #bb0066; font-weight: bold;">.main-inner</span> <span style="color: #bb0066; font-weight: bold;">.fauxcolumn-right-outer</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.footer-outer</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #007700;">body</span> {
<span style="color: #008800; font-weight: bold;">font-size</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">16px</span>;
}
<span style="color: #bb0066; font-weight: bold;">.header</span> <span style="color: #007700;">h1</span> {
<span style="color: #008800; font-weight: bold;">font-size</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
<span style="color: #008800; font-weight: bold;">margin-bottom</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">2px</span>;
}
<span style="color: #bb0066; font-weight: bold;">.header</span> {
<span style="color: #008800; font-weight: bold;">height</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">auto</span>;
}
<span style="color: #bb0066; font-weight: bold;">.header-inner</span> <span style="color: #bb0066; font-weight: bold;">.Header</span> <span style="color: #bb0066; font-weight: bold;">.descriptionwrapper</span> {
<span style="color: #008800; font-weight: bold;">margin-bottom</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">2px</span>;
}
}
</pre>
</div>
<br />
<b>Poznámka</b> - část stylů jsem získal na této stránce: <a href="http://exde601e.blogspot.cz/2012/05/make-blogger-more-printer-friendly.html">http://exde601e.blogspot.cz/2012/05/make-blogger-more-printer-friendly.html</a> , ale přidal jsem další na úpravu komentářů, kódu, velikosti hlavičky apod.<br />
<br />
Pokud je potřeba něco doladit, je dobré si otevřít stránku blogu v Chrome, vyvolat <b>DevTools</b> (F12), stiskem <b><i>Esc</i></b> vyvolat konzolu a na kartě <b>Emulation</b> zapnout <b>Screen</b> a jako <b>Css Media</b> vybrat <b>Print</b>. Lze si pak hrát s prvky a styly a docílit kýženého efektu pro tisk. Upravené styly je nutné uložit do <b><i>@media print</i></b> sekce, jak je popsáno v předchozí stati.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJsL37SfVzfiAIqDmNbv0AyjK_X0YZOF8Lhe3StGcYTWS4fg62AA81qZzadOsh0Um6FgAmeow7XuT7Qb-7dtdAMLWsg61u56PvP-SRW4WAQ-HYQXjkAiApqGrx-4PRBc2dRlGb42EU-Aw/s1600/DevTools2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="261" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJsL37SfVzfiAIqDmNbv0AyjK_X0YZOF8Lhe3StGcYTWS4fg62AA81qZzadOsh0Um6FgAmeow7XuT7Qb-7dtdAMLWsg61u56PvP-SRW4WAQ-HYQXjkAiApqGrx-4PRBc2dRlGb42EU-Aw/s400/DevTools2.JPG" width="400" /></a></div>
<br />
<br />
<h3>
Vložení ukázky kódu do příspěvku</h3>
Po zkopírování kódu ve Visual Studiu přes <b>Copy Html Markup</b> se na bloggeru přepne do <b>Html </b>režimu a vloží se kód:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCQ0w8bZRFSYI9ouLqXdtRwCJe5tePLBErhlLMuX1xkZWMGSAO00uVZv-dbITiNTLzJ8p-hyzKxG4OInCTt7Rpa1orK0Ut2zTLwEfKXSgIcwx7JJMSpBd2zJT1PrwvBbNX4ahEo_x0z5Y/s1600/Blog1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCQ0w8bZRFSYI9ouLqXdtRwCJe5tePLBErhlLMuX1xkZWMGSAO00uVZv-dbITiNTLzJ8p-hyzKxG4OInCTt7Rpa1orK0Ut2zTLwEfKXSgIcwx7JJMSpBd2zJT1PrwvBbNX4ahEo_x0z5Y/s400/Blog1.JPG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Kód se vkládá prostým kopírování, tedy Ctrl+V: </div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD0jMFEgYX2yHymB4nHlbSJEm2NFQnlPQ9_L7r1JrTMcoOzZ4FjOjM_3xHmF9lbjZqKGq25q24POw_9gfgv0vhcwrSv1PHobT8BYqiEkthZGOHq_b0OtEvJF6Md2zkfg3PYF9B_wQpMZQ/s1600/Blog2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD0jMFEgYX2yHymB4nHlbSJEm2NFQnlPQ9_L7r1JrTMcoOzZ4FjOjM_3xHmF9lbjZqKGq25q24POw_9gfgv0vhcwrSv1PHobT8BYqiEkthZGOHq_b0OtEvJF6Md2zkfg3PYF9B_wQpMZQ/s400/Blog2.JPG" width="400" /></a></div>
<br />
Poté se klikna na tlačítko <b>Napsat</b> a lze pokračovat v psaní v pohodlném Html editoru.<br />
<br />
A to je vše. Snad jen ukázka, jak vypadal například tisk před úpravou:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQF_Y9pH0psq7MNXbhVwTIeZGZJvuiY8yZygRopleq5muUKfT_rgRNl-2YUOhyphenhyphen3ZRP1W4wtsL5XWdK1Ob3i3n_hYAxc-otzcdYo0ZNHt1QfywXhyphenhyphen1LG_mBy3hrkENfqPX4r7aoR-qcZjM/s1600/PrintBefore.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQF_Y9pH0psq7MNXbhVwTIeZGZJvuiY8yZygRopleq5muUKfT_rgRNl-2YUOhyphenhyphen3ZRP1W4wtsL5XWdK1Ob3i3n_hYAxc-otzcdYo0ZNHt1QfywXhyphenhyphen1LG_mBy3hrkENfqPX4r7aoR-qcZjM/s400/PrintBefore.JPG" width="305" /></a></div>
<br />
a jak prokoukl po úpravě a přizpůsobení CSS:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbhyphenhyphendBoEdCRpoeh3GkcyzjzX0C6zkanxQxkLJLBtxvoYySG_udrsDPdTjpWXv8YuGQa-Gpjd8csDEK-aDkIib1dES27vaxYL-z_vwoGHm1nQjFOH5pZcFLgJoomQuWQnIivq65UZLpBSU/s1600/PrintAfter.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="385" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbhyphenhyphendBoEdCRpoeh3GkcyzjzX0C6zkanxQxkLJLBtxvoYySG_udrsDPdTjpWXv8YuGQa-Gpjd8csDEK-aDkIib1dES27vaxYL-z_vwoGHm1nQjFOH5pZcFLgJoomQuWQnIivq65UZLpBSU/s400/PrintAfter.JPG" width="400" /></a></div>
</div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com0tag:blogger.com,1999:blog-2993762679677061763.post-59309657605112055742016-01-21T20:54:00.001+01:002016-01-21T23:53:20.789+01:00Poznámky z code review - vytvoření xml řetězce<div style="text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwYDV6gqqNtW1XfDxmWlhopTbm28h_vrVUcpnUDvR8Rz5G-GWmbXDZphaNwfzzbrL6_Nf5Ypx6zXmtE1IRCStcluvEPn3bo_4vq73wWWQj7S-YQDcqxzsw4VN0WilHTXJ5M3p9fnl9A-s/s1600/index.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwYDV6gqqNtW1XfDxmWlhopTbm28h_vrVUcpnUDvR8Rz5G-GWmbXDZphaNwfzzbrL6_Nf5Ypx6zXmtE1IRCStcluvEPn3bo_4vq73wWWQj7S-YQDcqxzsw4VN0WilHTXJ5M3p9fnl9A-s/s200/index.jpg" width="100" /></a>Při práci s daty uloženými na SQL serveru je často nutné předat složitější data, než dovolují jednoduché datové typy vstupích parameterů. Tento problém řeší MS SQL server možností předat v parametru xml, se kterým lze následně v uložené proceduře pracovat. K vytvoření xml přistupují programátoři různě - ale obecně je asi dobré používat jeden přístup, který by měl vycházet i z možností jazyka a "vypadat" dobře.<br />
<br /></div>
<a name='more'></a>Samozřejmě nejjednodušší je si výsledné xml poskládat pomocí řetězců a <b>StringBuilder</b> třídy. Ale v následující ukázce programátor vytvořil Xml takto:<br />
<!--START-->
<pre><code><span class="User Types" style="color: #2b91af;">XmlDocument</span> <span class="identifier">doc</span> <span class="operator">=</span> <span class="keyword" style="color: blue;">new</span> <span class="User Types" style="color: #2b91af;">XmlDocument</span>();
<span class="User Types" style="color: #2b91af;">XmlElement</span> <span class="identifier">FactoryList</span> <span class="operator">=</span> <span class="identifier">doc</span><span class="operator">.</span><span class="identifier">CreateElement</span>(<span class="string" style="color: #a31515;">"ContractList"</span>);
<span class="keyword" style="color: blue;">foreach</span> (<span class="keyword" style="color: blue;">int</span> <span class="identifier">cid</span> <span class="keyword" style="color: blue;">in</span> <span class="identifier">contractIDs</span>)
{
<span class="User Types" style="color: #2b91af;">XmlElement</span> <span class="identifier">Factory</span> <span class="operator">=</span> <span class="identifier">doc</span><span class="operator">.</span><span class="identifier">CreateElement</span>(<span class="string" style="color: #a31515;">"Contract"</span>);
<span class="User Types" style="color: #2b91af;">XmlAttribute</span> <span class="identifier">ID</span> <span class="operator">=</span> <span class="identifier">doc</span><span class="operator">.</span><span class="identifier">CreateAttribute</span>(<span class="string" style="color: #a31515;">"ID"</span>);
<span class="identifier">ID</span><span class="operator">.</span><span class="identifier">Value</span> <span class="operator">=</span> <span class="identifier">cid</span><span class="operator">.</span><span class="identifier">ToString</span>();
<span class="identifier">Factory</span><span class="operator">.</span><span class="identifier">Attributes</span><span class="operator">.</span><span class="identifier">Append</span>(<span class="identifier">ID</span>);
<span class="identifier">FactoryList</span><span class="operator">.</span><span class="identifier">AppendChild</span>(<span class="identifier">Factory</span>);
}
<span class="identifier">doc</span><span class="operator">.</span><span class="identifier">AppendChild</span>(<span class="identifier">FactoryList</span>);
<span class="keyword" style="color: blue;">return</span> <span class="identifier">doc</span></code><span class="operator">.</span><span class="identifier">OuterXml</span>;</pre>
<br />
<!--END -->
Trochu kostrbaté, když je tu Linq, který to zvládne takto:
<!--here the code past begins--><br />
<br />
<pre><code><span class="keyword" style="color: blue;">return</span> <span class="keyword" style="color: blue;">new</span> <span class="User Types" style="color: #2b91af;">XDocument</span>(
<span class="keyword" style="color: blue;">new</span> <span class="User Types" style="color: #2b91af;">XElement</span>(
<span class="string" style="color: #a31515;">"ContractList"</span>,
<span class="keyword" style="color: blue;">from</span> <span class="identifier">c</span> <span class="keyword" style="color: blue;">in</span> <span class="identifier">contractIDs</span>
<span class="keyword" style="color: blue;">select</span> <span class="keyword" style="color: blue;">new</span> <span class="User Types" style="color: #2b91af;">XElement</span>(
<span class="string" style="color: #a31515;">"Contract"</span>,
<span class="keyword" style="color: blue;">new</span> <span class="User Types" style="color: #2b91af;">XAttribute</span>(<span class="string" style="color: #a31515;">"ID"</span>, <span class="identifier">c</span>)
)
)
)<span class="operator">.</span><span class="identifier">ToString</span>();</code></pre>
<br />
<div style="text-align: justify;">
<!--here the code past ends-->
V kódu jsou navíc nějaké další nedostatky - místní proměnné mají například názvy začínající velkými písmeny, původní kód byl odněkud zkopírován - alespoň soudě dle názvů proměnných.<br />
Ostatně kdo nikdy neprogramoval stylem <b><i>Ctrl+C/Ctrl+V</i></b> :-). </div>
mstrhttp://www.blogger.com/profile/17914336682364152828noreply@blogger.com3