C# - Hasznos apróságok alkalmazásainkban

forráskód letöltése
Bizonyára sokan találkoztunk már azzal a problémával, hogy az MS SQL Server Query Analyzer programjával lekérdezett rekordok dátumot tartalmazó oszlopaiban megjelennek az ezredmásodpercek, míg ha ugyanezt alkalmazásainkban tesszük, akkor nem. Cikkünkben bemutatjuk, milyen egyszerűen áthidalhatjuk ezt a kérdést. Cikkünk második felében bemutatjuk, hogyan készíthetünk olyan felsorolt típust, melynek elemei kombinálhatók egymással, ha a megfelelő attribútummal hozzuk létre a típust.
A mellékelt példa a MS SQL Server beépített Northwind adatbázisát használja, ennek megfelelően ennek telepítve kell lenni a számítógépen.
Idő ezredmásodperc értékének megjelenítése
Vannak olyan esetek, amikor az adattáblák dátum típusú oszlopaiban eltárolt értékek precíz megjelenítésére van szükségünk, vagyis látni szeretnénk az ezredmásodperceket is.
Ha ezt a műveletet az SqlDataAdapter vagy SqlCommand komponensek felhasználásával, valamint egy paraméterként megadott SELECT SQL utasítással végeztük el, akkor a Form-ra vagy a WebForm-ra helyezett DataGrid kontrolban a dátumnak csak a dátum összetevője jelent meg, valamint az időösszetevő óra, perc és másodperc összetevője.
Ugyanezt történt, ha az SqlDataReader osztály GetDateTime, vagy GetValue metódusaink valamelyikével kíséreltük meg kiolvasni az adatot, és betenni az említett vizuális kontrolba.
A formázást úgy kell elvégeznünk, hogy a visszakapott érték karakterlánc legyen, amely tartalmazza ezt az értéket. Ezt a SELECT utasításban kell megtennünk akkor, amikor azt értékül adjuk az SqlDataAdapter vagy a SqlCommand komponensek megfelelő property-jének.
A megadáshoz egy beépített konvertáló függvényt használhatunk fel, melynek meg kell adni az eredménytípust, az átalakítandó értékkel rendelkező oszlopot, valamint a karakterlánc hosszára vonatkozó értéket, mely három érték (0, 1 és 2) kombinációja hexadecimálisan. Az eredmény egy karakterlánc lesz, mely most már tartalmazza a várt értékeket. A példában ez a felületre helyezett TabControl ’Dátum kijelzése’ feliratú füle alatt látható. A kód pedig:
SqlDataAdapter adapter = new SqlDataAdapter("SELECT CONVERT(varchar, OrderDate, 21) FROM Orders",connection);
DataTable dt = new DataTable("Orders");
adapter.Fill(dt);
grid.DataSource = dt.DefaultView;
Felsorolt típus attribútummal
A mellékelt példa felületén a ’Saját enumerátor ’ fülre kattintva próbálhatjuk ki azt a lehetőséget, mely egy általunk létrehozott felsorolt típus értékeinek kombinálását jelenti egy számmal megadva.
A felsorolt típusokban konstans értékeket jelentő adatokat tárolunk, melyekre a felsorolt típus nevével és az adott elemmel hivatkozhatunk, gondoljunk csak az állományok megnyitásakor használt FileMode felsorolt típusra, melynek értékeit (Read, Write,…) használva tulajdonképpen egy szám konstanst adunk paraméterül az adott függvénynek, például a File osztály Open metódusának.
Vannak esetek, amikor a felsorolt típus elemeiből többet is meg szeretnénk adni úgy, hogy a felsorolt elemeket jelentő konstansokra hivatkozunk, és ezeket egy bitmintába helyezve választjuk ki az adott elemeket (akár egyszerre többet is). Ilyen például az állományok információs osztálya a FileInfo osztály Attributes property-je, mely FileAttributes típusú, és egy szám formájában jelzi, hogy az elemek közül melyekkel rendelkezik az adott állomány (Hidden, vagy ReadOnly, mely tulajdonságok nem zárják ki egymást).
A mellékelt példában azt modellezzük, hogy miként hozhatjuk létre a fent említett funkciójú típust, és ez hogyan használható fel. A példa érdekében létrehoztunk két azonos tartalmú felsorolt típust, melyeket csak a deklarációkor megadott attribútum különböztet meg egymástól. A felsorolt típusok deklarációja a következő:
[Flags]
private enum Elements1 : byte
{
  Elem1 = 0, Elem2 = 1, Elem3 = 2, Elem4 = 4, Elem5 = 8  
}
private enum Elements2 : byte
{
  Elem1 = 0, Elem2 = 1, Elem3 = 2, Elem4 = 4, Elem5 = 8  
}
Látható tehát, hogy csak az attribútumként megadott tulajdonságban különböznek. Az attribútum FlagsAttribute típusú, mely lehetővé teszi, hogy a típus elemei kombinálhatók legyenek egymással.
A példában, egy listában jelennek meg a típusok elemei, szám szerint öt. Az elemeknek megfelelő szám konstansokat megadva az ’Elemek kombinációja’ mezőben megjelenik az adott elem nevét jelentő karakterlánc, például nullát írva az ’Elemek választása’ mezőbe és a ’Kiválasztás’ gombra kattintva az Elem1 érték jelenik meg.
Ezzel a tulajdonsággal mindkét felsorolt típus rendelkezik, azonban olyan számot megadva, mely nem szerepel konstansként egyik elem mellett sem, de egyenlő néhány elem konstansainak összegével, akkor a megfelelő elemek együttesen jelennek meg a Format metódusát felhasználva abban az esetben, ha az attribútummal deklarált felsorolt típus elemeire hivatkozunk ily módon. A másik típus elemeinek ilyetén megadása nem lehetséges, vagyis ilyen számot megadva maga a szám jelenik meg a Format függvény meghívása után. A metódusnak meg kell adni paraméterként a felsorolt típust, a kérdéses számot, valamint egy formázó string-et, mely esetünkben, mivel az elemek megjelenítése a vágyunk, egy „G”.
A példában eldönthetjük, hogy melyik felsorolt típust kívánjuk használni, amennyiben bejelöljük, vagy jelöletlenül hagyjuk a jelölőnégyzetet. Az attribútummal deklarált felsorolt típus elemeire hivatkozva a 3-as szám megadásával az ’Elem1, Elem2’ eredményláncot kapjuk, míg ha ugyanezt a másik típus elemeivel tesszük, akkor a 3-as számot, vagyis itt az elemek nem kombinálhatók. A megjelenítés a következőképpen valósul meg:
byte en = 0;
...
if (cb.Checked)
{
  enumText.Text = Enum.Format(typeof(Elements1),en,"g");
}
else
{
  enumText.Text = Enum.Format(typeof(Elements2),en,"g");
}
A második paraméter típusának meg kell egyeznie a felsorolt típus elemeinek típusával.