sobota, 8. januára 2011

C# - Navrátené objekty anonymného typu.
Čo s nimi?

Jedna z novších čŕt jazyku C# (od C# 3.0) sú anonymné typy (vytváranie objektov neznámeho typu, respektíve objektov žiadneho deklarovaného typu). Sú vynikajúce pri použití s technológiou LINQ, no je problém s konzumovaním týchto objektov po navrátení z funkcie. Anonymné objekty sa dajú navrátiť jedine ako typu object, ktorý potom však nemáme ako využiť bez toho aby sme ho explicitne pretypovali (explicit cast). No do akého typu - ako - chceme pretypovať objekt, keď je anonymný a jeho typ bol vytvorený takzvane on-the-fly (za behu)?

(Neviem sa tu veľmi spriateliť s formátovaním článkov na Google blogu. Kuknite na to na mojej stránke, kde to občas aj updateujem)

Okrem argumentu, že by sme sa o to nemali radšej ani pokúšať, že anonymné objekty sa nemajú navrácať z metód a mali by sa použiť priamo v metóde kde boli vytvorené (všetko veľmi dobré a opodstatnené rady), sa nám poskytuje ešte niekoľko možností. Na jednu konkrétne zaujímavú som naďabil nedávno a chcel by som sa o nej zmieniť:

Pokiaľ tvoríme aplikáciu pre ".NET Framework 4" profil a nie ".NET Framework 4 Client Profile", môžeme využiť jeden typ z namespace-u System.Web.Routing (knižnica System.Web.dll). V nastaveniach projektu zmeníme profil na .NET Framework 4 (implikácie čoho nám musia byť jasné), aby sme mohli pridať do projektu referenciu na knižnicu System.Web.dll

V našom projekte potom stačí pridať jednu "using" klauzulu:

using System.Web.Routing;

A na nasledujúcej ukážke malého programíku vám ukážem čo a ako s anonymným objektom navráteným z nejakej funkcie:

class Program
{
  static void Main(string[] args)
  {
    object anonym = Metoda_Vracia_Objekt_Anonymneho_Typu(); //CO S TYM?

    //Uz viem! Pouzijem RouteValueDictionary zo System.Web.dll
    RouteValueDictionary rvd = new RouteValueDictionary(anonym);

    //a dalej je vsetko vesele :-)
    Console.WriteLine("Ahoj, volám sa {0} a pracujem ako {1}", rvd["Meno"], rvd["Povolanie"]);
  }
 
  private static object Metoda_Vracia_Objekt_Anonymneho_Typu()
  {
    return new { Id = 1, Meno = "Peter Perhác", Povolanie = "softwareový vývojár" };
  }
}

Tento program, ako sa dá očakávať, produkuje nasledovnú vetu (číročistá pravda):
Ahoj, volám sa Peter Perháč a pracujem ako softwareový vývojár

Ta fasa, ňe?

Načo je nám toto dobré?

Nuž... ako som vravel, vyhúť sa navracaniu anonymných objektov z metód je dobrá rada. Vyhnite sa tomu ak môžete. Ja som narazil na potrebu kontrolovania stavu anonymných objektov pri testovaní ASP.NET MVC2 webovej aplikácie.

Niektoré z action methods mojich kontrolerov navracali JsonResult. V JSON notácii som tam mal nejaké DATA, ktoré som do JSON formy dával cez anonymné objekty. V mojom Unit teste som chcel potom overiť, či navrátený ActionResult po zavolaní action method na kontroleri naozaj navracia JsonResult objekt a či teda Data object toho JsonResult-u má správne nastavené hodnoty svojich vlastností.

Toto sa dá celkom jednoducho, takto v kontext ASP.NET MVC2 webovej aplikácie, pretože správny profil je už zvolený, referencia na System.Web.dll je už v projekte (teda nemusí byť za sekundu si ju môžeme pridať), stačí len naimportovať správny namespace System.Web.Routing a z neho použiť triedu RouteValueDictionary.

Tento anonymný objekt, JSON Data, môžeme podať RouteValueDictionary v jej konštruktore a potom už len vyťahovať jednotlivé vlastnosti anonymného objektu zo slovníka použitím jeho indexer-u.

Myslím si, že zbytočne veľa slov o niečom, čo vidíte najjednoduchšie z hore-uvedeného príkladu.

Veselé kódovanie a veľa Wow! pocitov

Žiadne komentáre:

Zverejnenie komentára