Mi mást is mondhatnék: http://weblogs.asp.net/scottgu/archive/2010/06/28/introducing-iis-express.aspx
2010. június 29., kedd
2010. június 23., szerda
Stílusrendőrség
A különbőző névadási, kódolási konvenciók betartása létfontosságú, ha ugyanazon a codebase-en többen is dolgoznak. Más kódjának megértése amúgy se tartozik a legtriviálisab feladatok közé, ha pedig még a "közös nyelv" sincs meg, akkor igazi PITA. Egy baj van a dologgal, hogy a betartatása igazi robotmunka - akkor viszont nosza, csináltassuk robotokkal!
Több tool is elérhető a témakörben, például az FxCop, ami a már lefordított assembly-t elemezve ömleszti ránk a jótanácsokat, de ma nem róla lesz szó, hanem a testvéréről, a StyleCop-ról. Ő a forráskódot analizálja, ennélfogva némileg más szempontok szerint tudja segíteni a munkánkat.
Csináltam egy gyors teszet: letöltöttem az install .msi-t, a Visual Studio-ban csináltam egy új konzol alkalmazást, és az automatikusan legenerált alkalmazás-vázat egy magas színvonalú "Hello, World!" applikációvá bővítettem ki:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace StyleCopTest { class Program { static void Main(string[] args) { Console.WriteLine("Hello, StyleCop!"); } } }Ezután elindítottam a Tools menübe beépülő StyleCop-ot (Run StyleCop), ami megvizsgálta a kódot, és a standard Error list ablakban (amiben a fordításkor az Error-ok, Warningok jelennek meg), néhány Warning képépben materializálódott a végeredmény.
Ezután átszabtam úgy a kódot, hogy megfeleljek az alapból beállított szabályok mindegyikének.
Ezek között voltak olyanok, amikkel nagyon egyetértettem (pl. minden osztályon, metóduson legyen XML komment), valamire azt mondtam, hogy hát végülis jó, legyen (mindenképp legyen kiírva az access modifier az class-ok elé), valamit kimondottam furcsálltam (a using-okat hozzuk be a namespace alá).
A file elejére egy copyright note-ot reklamált, amit saját kútfőből nem is tudtam összehozni, szerencsére az adott warning kódja (SA1634) alapján a SyleCop doksiból kiderült, hogy pontosan milyenre vágyik. Végül ez lett a "Hello, StyleCop!" alkalmazásból:
// <copyright file="Program.cs" company="Öt Perc DotNet"> // Copyright (C) 2010 http://otperc.net // </copyright> namespace StyleCopTest { using System; using System.Collections.Generic; using System.Linq; using System.Text; /// <summary> /// A summary for the Program class. /// </summary> internal class Program { /// <summary> /// A comment for the Main method. /// </summary> /// <param name="args">A comment for the args parameter.</param> public static void Main(string[] args) { Console.WriteLine("Hello, StyleCop!"); } } }
Szerencsére ott, ahol nem értünk egyet beépített stílusrendőrünkkel, ott lehetőség van a konfigurálásra, vagy akár új szabály létrehozására. A StyleCop a build folyamatba is bepíthető, így akár automatikus visszajelzést kaphatunk, ha valaki a csapatunkból partizánakciókba kezd kódolási stílus terén.
2010. június 15., kedd
Kínzó kérdés
Az miért van, hogy lézernyomtatóból tudnak csinálni
- fekete-fehéret,
- színeset,
- fénymásolósat,
- scannelőset,
- faxgépeset,
- egyoldalas-nyomtatósat,
- kétoldalas-nyomtatósat,
- n-oldalas-nyomtatósat,
- összefűzőset,
- szétvágósat,
- dokumentum-megőrzőset,
- dokumentum-megsemmisítőset,
- százezer forintosat,
- egymillió forintosat,
- tízmillió forintosat,
2010. június 11., péntek
Olvasóink küldték rovat
"Névtelen" olvasónk kommentjében érkezett a következő "mit ír ki" rejtvény:
Console.WriteLine("{0}"); Console.WriteLine("{0}", "{0}");
Én ezt még ennyivel megfejelném:
Console.WriteLine(string.Format("{0}")); Console.WriteLine(string.Format("{0}", "{0}"));
A kérdést már fel se teszem
object o1 = true; object o2 = true; Console.WriteLine(o1 == o2);
2010. június 10., csütörtök
GMail "plusszos címzés"
Tudják mi az email címem?
Hát gerely+1@mail.com. Vagy gerely+2@gmail.com. Vagy gerely+akarmi@gmail.com.
A gmail ugyanis figyelmen kívül hagyja a usernévben a "+" jel mögötti rész, a levél így is megérkezik a postafiókba. A "figyelmen kívül hagyja" nem is teljesen pontos, mert cízett (To:) mezőben ott lesz, tehát ez alapján tudunk címkézni, filterezni.
Akkor is nagyon jól tud jönni ez a feature, ha pl. egy regisztrációs folyamatot tesztelünk, ahol mindig egyedi email címeket kell megadni, de érthető okokból nem szeretnénk 1000 postafiókot létrehozni...
További trükközésre nyílik lehetőseg a névben elhelyezett pont karakterrel.
Részletek a GMail Blog-on: http://gmailblog.blogspot.com/2008/03/2-hidden-ways-to-get-more-from-your.html
Megmondom mit ír ki
A tegnapi kérdés megoldása: False, True... Gondolhattátok volna? :) Hehehe. Na de miért, az a nagy kérdés, azt is megmondom.
Szóval a második összehasonlítás értéke nem azért True, mert mindkét string "true", illetve azért, csak nem úgy, hanem... ehh. Kezdjük az elejéről.
A .NET-ben a string immutable, ami annyit tesz, hogy az értéke sosem változhat meg. Egyszer értéket adsz neki, úgy marad. A különböző sztring-mogyorózó műveletek is (.Replace(), .Substring(), .Trim(), stb), bár példány-metódusok, nem az adott példány állapotát változtatják meg, hanem egy új string példányt adnak vissza.
Nézzük példaként az alábbi kódot:
object o1 = "true"; object o2 = "true"; Console.WriteLine(o1 == o2);Itt mind az első, mind a második sorban leírt sztring-konstans értéke "true", és az is marad, megváltoztathatlanul, örökre. De akkor minek kétszer tárolni, ha úgy is ugyanaz mindkettő, és nem lehet változtatni rajta?
Nos, nem kell kétszer tárolni, sőt, ami a legjobb, ezzel a spórolással nekünk nem is kell törődni, mert a .NET CLR automatikusan megteszi helyettünk. Csak egy darab "true" értékű string példány fog létrejönni, és mind az o1, mind az o2 referencia rá fog mutatni. Így o1 egyenlő lesz o2-vel - de ehhez az egyenlőség-vizsgálathoz már nem sok köze van a "true" stringnek, az összehasonlítás azt figyeli, hogy referenciálisan egyenlőek-e ("ugyanoda mutatnak-e", mondaná az unmanaged világ).
Ebben a kódban viszont a StringBuilder .ToString()-je "bekavar", nem az intern pool példányát fogja visszaadni, hanem egy újat, így ez az o1 ami nem lesz referenciálisan egyenlő a o2-vel:
object o1 = new StringBuilder("true").ToString(); object o2 = "true"; Console.WriteLine(o1 == o2);
2010. június 9., szerda
Mit ír ki?
var sb = new StringBuilder("true"); object o1 = sb.ToString(); object o2 = "true"; Console.WriteLine(o1 == "true"); Console.WriteLine(o2 == "true");
2010. június 3., csütörtök
Az [Obsolete] attribútum esete a #pragmával (és sok más érdekes)
Adott a szituáció, hogy van egy metódus a kódunkban, ami elavult, régi, legacy, azóta van jobb, azt kéne használni, a régit pedig nem kéne hívni. A legegyszerűbb lenne egyszerűen kidobni, de sajnos nem lehet, mert van néhány szintén elavult, régi, legacy kód, ami hívja, és azokhoz nem akarunk / tudunk hozzányúlni.
Mindenképp szeretnénk viszont biztosítani, hogyaz újonnan íródó kódok már az új metódust használják. Milyen módszerek vannak?
- Írunk egy emailt mindenkinek, hogy használja az új metódust - ez EPIC FAIL.
- A metódus XML kommentjében (ugye minden metóduson van?) jelezzük, hogy ne használd, és miért ne használd, és mit kell használni helyette - eggyel jobb, sőt, kiegészítő megoldásként kimondottan jó ötlet.
- Megjelöljük az [Obsolete] attribútummal. - na, ez az, ez kell nekünk, az ultimate, überfrankó megoldás!
Remélhetőleg - de messze nem biztos. Sokat segít, ha egyébként nem vagyunk tele warningokkal - azok sokszor amúgy is inkább error-ok, mint warningok - de még akkor sem hundert Prozent.
Van ugyan egy overload-ja az Obsolete attribútumnak, ahol egy bool paraméterben megmondhatjuk, hogy ne warning-ot, hanem error-t generáljon az elavult metódus hívásakor - azt már csak észreveszi a fejlesztő, hogy nem fordul a kódja.
Van viszont egy hátulütője is ennek a megoldásnak: az a régi, legacy kód sem fog fordulni, amit viszont nem akarunk átírni az új metódus használatára. Ennyi erővel ki is hajinthatnánk az elavult metódusunkat, úgy se lehet hívni sehogy (bár reflection-nel pl. lehet, de egyelőre maradjunk a keresztény kultúrkörben).
Meg egyébként is, ne bolygassuk a múltat, minden maradjon a régiben, ne jöjjenek mindenféle warningok, csak ha valami új kód próbálná hívni az elavult metódust, csapjon a fejlesző kezére a Visual Studio!
Maradjunk tehát az [Obsolete] annál az overload-jánál, ami nem dob hibát:
[Obsolete] static void OldMethod() { Console.WriteLine("Don't call me!"); } static void Main(string[] args) { OldMethod(); }Ha ezt így lefordítjuk, egy "'OldMethod()' is obsolete" warningot kapunk. Tegyük fel, hogy ez az a pont, ahol a régi kód hív, tűntessük el a warningot:
static void Main(string[] args) { #pragma warning disable 612 OldMethod(); #pragma warning restore 612 }Megjegyzés: ha az Obsolete-nek azt az overload-ját használjuk, ami saját üzenetet ír ki, akkor nem 612-es, hanem 618-as kódú warning generálódik!
Eddig remek. Most már csak azt kéne elérni, hogy a Visual Studio egy warning-nál erőteljesebben hozza a tudomásunkra, ha olyat próbálnánk hívni, amit nem kéne.
Nosza, vegyük rá, hogy ezeket a warningokat hibaként kezelje! A projektünk properties ablakában, a build fül "Treat warnings as errors" szekcióban pont ezt tehetjük meg:
Ezzel el is értük, amit akartunk: a világ ismét megmenekült a pusztulástól.
Viszontlátásra.

